Skip to content

Commit

Permalink
fix(flagship): Make android namespace match package name
Browse files Browse the repository at this point in the history
The namespace for native android code was always set to
com.brandingbrand.reactnative.and.{config.name}, rather than using the defined ID. This lead to some
issues with starting activities and imports.

BREAKING CHANGE: If anything hard codes the android native project path (ie.
android/app/src/main/java/com/brandingbrand/reactnative/and/project-name), it will need to be
updated to account for the dynamic package name. Flagship now exports its own modules, so
`flagship.path.android.nativeProjectPath(config)` can be used to get the directory without hard
coding a path.
  • Loading branch information
nathan-sankbeil committed Sep 24, 2019
1 parent 42aa327 commit e53e362
Show file tree
Hide file tree
Showing 16 changed files with 169 additions and 39 deletions.
4 changes: 2 additions & 2 deletions packages/flagship/android/app/BUCK
Original file line number Diff line number Diff line change
Expand Up @@ -35,13 +35,13 @@ android_library(

android_build_config(
name = 'build_config',
package = 'com.brandingbrand.reactnative.and.flagship',
package = 'CONFIG_BUNDLE_ID',
)

android_resource(
name = 'res',
res = 'src/main/res',
package = 'com.brandingbrand.reactnative.and.flagship',
package = 'CONFIG_BUNDLE_ID',
)

android_binary(
Expand Down
2 changes: 1 addition & 1 deletion packages/flagship/android/app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ android {

defaultConfig {
multiDexEnabled true
applicationId "com.brandingbrand.reactnative.and.flagship"
applicationId "CONFIG_BUNDLE_ID"
minSdkVersion rootProject.ext.minSdkVersion
targetSdkVersion rootProject.ext.targetSdkVersion
versionName project.VERSION_NAME
Expand Down
2 changes: 1 addition & 1 deletion packages/flagship/android/app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.brandingbrand.reactnative.and.flagship">
package="CONFIG_BUNDLE_ID">

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.brandingbrand.reactnative.and.flagship;
package CONFIG_BUNDLE_ID;

import android.annotation.SuppressLint;
import android.content.Context;
Expand Down Expand Up @@ -44,4 +44,4 @@ public void setEnv(String name, Promise promise) {

promise.resolve(null);
}
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.brandingbrand.reactnative.and.flagship;
package CONFIG_BUNDLE_ID;

import com.facebook.react.ReactPackage;
import com.facebook.react.bridge.NativeModule;
Expand All @@ -21,4 +21,4 @@ public List<NativeModule> createNativeModules(final ReactApplicationContext reac
add(new EnvSwitcher(reactContext));
}};
}
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.brandingbrand.reactnative.and.flagship;
package CONFIG_BUNDLE_ID;

import com.reactnativenavigation.controllers.SplashActivity;

Expand All @@ -7,4 +7,4 @@ public class MainActivity extends SplashActivity {
public int getSplashLayout() {
return R.layout.splash;
}
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.brandingbrand.reactnative.and.flagship;
package CONFIG_BUNDLE_ID;

import android.app.Application;

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.brandingbrand.reactnative.and.flagship;
package CONFIG_BUNDLE_ID;

import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
Expand All @@ -24,4 +24,4 @@ public Map<String, Object> getConstants() {

return constants;
}
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.brandingbrand.reactnative.and.flagship;
package CONFIG_BUNDLE_ID;

import com.facebook.react.ReactPackage;
import com.facebook.react.bridge.NativeModule;
Expand All @@ -21,4 +21,4 @@ public List<NativeModule> createNativeModules(final ReactApplicationContext reac
add(new NativeConstants(reactContext));
}};
}
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.brandingbrand.reactnative.and.flagship;
package CONFIG_BUNDLE_ID;

import android.support.annotation.Nullable;

Expand Down
9 changes: 9 additions & 0 deletions packages/flagship/src/commands/init.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ export interface HandlerArgs {
env: string;
}

const TEMPLATE_ANDROID_PACKAGE = 'com.brandingbrand.reactnative.and.flagship';

export const command = 'init [platform]';

export const describe = 'initialize FLAGSHIP for [platform]';
Expand Down Expand Up @@ -127,8 +129,15 @@ function initAndroid(
// Clone the boilerplate into the project
fs.clone('android');

// The id should be defined, but set it to a default if it's not for compatibility reasons
const pkgId = configuration.bundleIds && configuration.bundleIds.android ?
configuration.bundleIds.android.toLowerCase() :
`com.brandingbrand.reactnative.and.${configuration.name.toLowerCase()}`;

// Rename the boilerplate project with the app name
rename.source('FLAGSHIP', configuration.name, 'android');
rename.source('CONFIG_BUNDLE_ID', pkgId, 'android');
rename.pkgDirectory(TEMPLATE_ANDROID_PACKAGE, pkgId, path.android.mainPath(), 'java');
rename.files('FLAGSHIP', configuration.name, 'android');

fastlane.configure(path.android.fastfilePath(), configuration); // Update Fastfile
Expand Down
33 changes: 33 additions & 0 deletions packages/flagship/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import * as android from './lib/android';
import * as cocoapods from './lib/cocoapods';
import * as deeplinking from './lib/deeplinking';
import * as env from './lib/env';
import * as fastlane from './lib/fastlane';
import * as fs from './lib/fs';
import * as ios from './lib/ios';
import * as link from './lib/link';
import * as modules from './lib/modules';
import * as nativeConstants from './lib/native-constants';
import * as os from './lib/os';
import * as path from './lib/path';
import * as rename from './lib/rename';
import * as version from './lib/version';
import * as web from './lib/web';

export {
android,
cocoapods,
deeplinking,
env,
fastlane,
fs,
ios,
link,
modules,
nativeConstants,
os,
path,
rename,
version,
web
};
4 changes: 3 additions & 1 deletion packages/flagship/src/lib/fs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import {
copySync,
ensureDirSync,
ensureSymlinkSync,
moveSync,
pathExistsSync,
readdirSync,
readFileSync,
Expand All @@ -18,7 +19,8 @@ export {
ensureDirSync,
renameSync,
pathExistsSync,
ensureSymlinkSync
ensureSymlinkSync,
moveSync
};

import * as helpers from '../helpers';
Expand Down
10 changes: 5 additions & 5 deletions packages/flagship/src/lib/path.ts
Original file line number Diff line number Diff line change
Expand Up @@ -169,14 +169,14 @@ function getManifestPath(): string {
* @returns {string} The path to the native project.
*/
function getNativeProjectPathAndriod(configuration: Config): string {
const pkgId = configuration.bundleIds && configuration.bundleIds.android ?
configuration.bundleIds.android :
`com.brandingbrand.reactnative.and.${configuration.name}`;

return resolvePathFromProject(
getMainPath(),
'java',
'com',
'brandingbrand',
'reactnative',
'and',
configuration.name.toLowerCase()
...pkgId.toLowerCase().split('.')
);
}

Expand Down
89 changes: 73 additions & 16 deletions packages/flagship/src/lib/rename.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,54 @@ export function source(oldName: string, newName: string, ...pathComponents: stri
logInfo(`renamed project within source in ${directory}`);
}

/**
* Updates the directory structure to match a new namespace
*
* @param {string} oldPkg The old package name to replace.
* @param {string} newPkg The new package name to use.
* @param {...string} pathComponents Path components to the directory in which to
* replace the project name.
*/
export function pkgDirectory(oldPkg: string, newPkg: string, ...pathComponents: string[]): void {
const directory = path.project.resolve(...pathComponents);
const oldPathPart = oldPkg.replace(/\./g, '/');
const newPathPart = newPkg.replace(/\./g, '/');

try {
const results = getMatchingFiles(directory, oldPathPart);

// Rename matching paths
results.forEach(oldPath => {
const newPath = oldPath.replace(oldPathPart, newPathPart).toLowerCase();
fs.moveSync(oldPath, newPath);
});

// since we only moved the bottom-most directory, traverse through the old
// package directories to delete any empty package folders
oldPkg
.split('.')
.reduce<string[]>((parts, part, index, arr) => {
const pattern = [...arr.slice(0, index), part].join('/');
parts.push(...getMatchingFiles(directory, pattern));
return parts;
}, [])
.reverse()
.forEach(dir => {
const contents = fs.pathExistsSync(dir) && fs.readdirSync(dir);
if (Array.isArray(contents) && contents.length === 0) {
fs.removeSync(dir);
}
});

} catch (err) {
logError('renaming project files', err);
process.exit(1);
}

logInfo(`renamed project files in ${directory}`);
}


/**
* Replaces the project name within boilerplate file names.
*
Expand All @@ -46,21 +94,7 @@ export function files(oldName: string, newName: string, ...pathComponents: strin
const directory = path.project.resolve(...pathComponents);

try {
const globOptions = {
nosort: true,
dot: true
};

// Find files/directories to be renamed
const results = [
...sync(directory + '/**/*' + oldName + '*', globOptions),
...sync(directory + '/**/*' + oldName.toLocaleLowerCase() + '*', globOptions)
];

// Sort the results so highest depth paths are replaced first
results.sort((a, b) => {
return b.length - a.length;
});
const results = getMatchingFiles(directory, oldName);

// Rename each path
results.forEach(oldPath => {
Expand All @@ -79,5 +113,28 @@ export function files(oldName: string, newName: string, ...pathComponents: strin
process.exit(1);
}

logInfo(`renaming project files in ${directory}`);
logInfo(`renamed project files in ${directory}`);
}

function getMatchingFiles(directory: string, oldName: string): string[] {
const globOptions = {
nosort: true,
dot: true
};

// Find files/directories to be renamed
const results = [
...sync(directory + '/**/*' + oldName + '*', globOptions),
...sync(directory + '/**/*' + oldName.toLocaleLowerCase() + '*', globOptions)
];

// Remove duplicate paths from the results array
const uniqueResults = Array.from(new Set(results));

// Sort the results so highest depth paths are replaced first
uniqueResults.sort((a, b) => {
return b.length - a.length;
});

return uniqueResults;
}
31 changes: 30 additions & 1 deletion yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -15952,7 +15952,36 @@ webpack-sources@^1.1.0, webpack-sources@^1.4.0, webpack-sources@^1.4.1:
source-list-map "^2.0.0"
source-map "~0.6.1"

webpack@^4.16.5, webpack@^4.23.1:
[email protected]:
version "4.39.3"
resolved "https://registry.yarnpkg.com/webpack/-/webpack-4.39.3.tgz#a02179d1032156b713b6ec2da7e0df9d037def50"
integrity sha512-BXSI9M211JyCVc3JxHWDpze85CvjC842EvpRsVTc/d15YJGlox7GIDd38kJgWrb3ZluyvIjgenbLDMBQPDcxYQ==
dependencies:
"@webassemblyjs/ast" "1.8.5"
"@webassemblyjs/helper-module-context" "1.8.5"
"@webassemblyjs/wasm-edit" "1.8.5"
"@webassemblyjs/wasm-parser" "1.8.5"
acorn "^6.2.1"
ajv "^6.10.2"
ajv-keywords "^3.4.1"
chrome-trace-event "^1.0.2"
enhanced-resolve "^4.1.0"
eslint-scope "^4.0.3"
json-parse-better-errors "^1.0.2"
loader-runner "^2.4.0"
loader-utils "^1.2.3"
memory-fs "^0.4.1"
micromatch "^3.1.10"
mkdirp "^0.5.1"
neo-async "^2.6.1"
node-libs-browser "^2.2.1"
schema-utils "^1.0.0"
tapable "^1.1.3"
terser-webpack-plugin "^1.4.1"
watchpack "^1.6.0"
webpack-sources "^1.4.1"

webpack@^4.23.1:
version "4.39.1"
resolved "https://registry.yarnpkg.com/webpack/-/webpack-4.39.1.tgz#60ed9fb2b72cd60f26ea526c404d2a4cc97a1bd8"
integrity sha512-/LAb2TJ2z+eVwisldp3dqTEoNhzp/TLCZlmZm3GGGAlnfIWDgOEE758j/9atklNLfRyhKbZTCOIoPqLJXeBLbQ==
Expand Down

0 comments on commit e53e362

Please sign in to comment.