Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: update gradle files for 0.73 support #917

Merged
merged 2 commits into from
Feb 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
133 changes: 48 additions & 85 deletions packages/core/android/build.gradle
Original file line number Diff line number Diff line change
@@ -1,40 +1,63 @@
buildscript {
// Buildscript is evaluated before everything else so we can't use getExtOrDefault
def kotlin_version = rootProject.ext.has('kotlinVersion') ? rootProject.ext.get('kotlinVersion') : project.properties['AnalyticsReactNative_kotlinVersion']
def kotlin_version = rootProject.ext.has("kotlinVersion") ? rootProject.ext.get("kotlinVersion") : project.properties["AnalyticsReactNative_kotlinVersion"]

repositories {
google()
jcenter()
mavenCentral()

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Was curious about this - found https://developer.android.com/build/jcenter-migration which explains why you needed to do this 😄
(And I guess it also just matches the new template)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was actually surprised that we hadn't done this before!
I remember it used to be very noisy in analytics-android/kotlin

}

dependencies {
classpath 'com.android.tools.build:gradle:4.0.1'
classpath "com.android.tools.build:gradle:7.2.1"
// noinspection DifferentKotlinGradleVersion
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
}
}

apply plugin: 'com.android.library'
apply plugin: 'kotlin-android'
def isNewArchitectureEnabled() {
return rootProject.hasProperty("newArchEnabled") && rootProject.getProperty("newArchEnabled") == "true"
}

apply plugin: "com.android.library"
apply plugin: "kotlin-android"

if (isNewArchitectureEnabled()) {
apply plugin: "com.facebook.react"
}

def getExtOrDefault(name) {
return rootProject.ext.has(name) ? rootProject.ext.get(name) : project.properties['AnalyticsReactNative_' + name]
return rootProject.ext.has(name) ? rootProject.ext.get(name) : project.properties["AnalyticsReactNative_" + name]
}

def getExtOrIntegerDefault(name) {
return rootProject.ext.has(name) ? rootProject.ext.get(name) : (project.properties['AnalyticsReactNative_' + name]).toInteger()
return rootProject.ext.has(name) ? rootProject.ext.get(name) : (project.properties["AnalyticsReactNative_" + name]).toInteger()
}

def supportsNamespace() {
def parsed = com.android.Version.ANDROID_GRADLE_PLUGIN_VERSION.tokenize('.')
def major = parsed[0].toInteger()
def minor = parsed[1].toInteger()

// Namespace support was added in 7.3.0
return (major == 7 && minor >= 3) || major >= 8
}

android {
compileSdkVersion getExtOrIntegerDefault('compileSdkVersion')
buildToolsVersion getExtOrDefault('buildToolsVersion')
if (supportsNamespace()) {
namespace "com.segmentanalyticsreactnative"

sourceSets {
main {
manifest.srcFile "src/main/AndroidManifestNew.xml"
}
}
}

compileSdkVersion getExtOrIntegerDefault("compileSdkVersion")

defaultConfig {
minSdkVersion 21
targetSdkVersion getExtOrIntegerDefault('targetSdkVersion')
compileSdkVersion = getExtOrIntegerDefault('compileSdkVersion')
versionCode 1
versionName "1.0"
minSdkVersion getExtOrIntegerDefault("minSdkVersion")
targetSdkVersion getExtOrIntegerDefault("targetSdkVersion")

}

Expand All @@ -43,9 +66,11 @@ android {
minifyEnabled false
}
}

lintOptions {
disable 'GradleCompatible'
disable "GradleCompatible"
}

compileOptions {
sourceCompatibility JavaVersion.VERSION_11
targetCompatibility JavaVersion.VERSION_11
Expand All @@ -54,80 +79,18 @@ android {

repositories {
mavenCentral()
jcenter()
google()

def found = false
def defaultDir = null
def androidSourcesName = 'React Native sources'

if (rootProject.ext.has('reactNativeAndroidRoot')) {
defaultDir = rootProject.ext.get('reactNativeAndroidRoot')
} else {
defaultDir = new File(
projectDir,
'/../../../node_modules/react-native/android'
)
}

if (defaultDir.exists()) {
maven {
url defaultDir.toString()
name androidSourcesName
}

logger.info(":${project.name}:reactNativeAndroidRoot ${defaultDir.canonicalPath}")
found = true
} else {
def parentDir = rootProject.projectDir

1.upto(5, {
if (found) return true
parentDir = parentDir.parentFile

def androidSourcesDir = new File(
parentDir,
'node_modules/react-native'
)

def androidPrebuiltBinaryDir = new File(
parentDir,
'node_modules/react-native/android'
)

if (androidPrebuiltBinaryDir.exists()) {
maven {
url androidPrebuiltBinaryDir.toString()
name androidSourcesName
}

logger.info(":${project.name}:reactNativeAndroidRoot ${androidPrebuiltBinaryDir.canonicalPath}")
found = true
} else if (androidSourcesDir.exists()) {
maven {
url androidSourcesDir.toString()
name androidSourcesName
}

logger.info(":${project.name}:reactNativeAndroidRoot ${androidSourcesDir.canonicalPath}")
found = true
}
})
}

if (!found) {
throw new GradleException(
"${project.name}: unable to locate React Native android sources. " +
"Ensure you have you installed React Native as a dependency in your project and try again."
)
}
}

def kotlin_version = getExtOrDefault('kotlinVersion')
def kotlin_version = getExtOrDefault("kotlinVersion")

dependencies {
// noinspection GradleDynamicVersion
api 'com.facebook.react:react-native:+'
// For < 0.71, this will be from the local maven repo
// For > 0.71, this will be replaced by `com.facebook.react:react-android:$version` by react gradle plugin
//noinspection GradleDynamicVersion
implementation "com.facebook.react:react-native:+"
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
implementation project(path: ':segment_sovran-react-native')
// Requires sovran for communication
implementation project(path: ':segment_sovran-react-native')
}

7 changes: 4 additions & 3 deletions packages/core/android/gradle.properties
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
AnalyticsReactNative_kotlinVersion=1.7.0
AnalyticsReactNative_compileSdkVersion=29
AnalyticsReactNative_buildToolsVersion=29.0.2
AnalyticsReactNative_targetSdkVersion=29
AnalyticsReactNative_minSdkVersion=21
AnalyticsReactNative_targetSdkVersion=31
AnalyticsReactNative_compileSdkVersion=31
AnalyticsReactNative_ndkversion=21.4.7075529
3 changes: 3 additions & 0 deletions packages/core/android/src/main/AndroidManifestNew.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
</manifest>
99 changes: 98 additions & 1 deletion packages/core/src/__tests__/util.test.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { chunk, allSettled } from '../util';
import { UserTraits } from '../types';
import { chunk, allSettled, deepCompare } from '../util';

describe('#chunk', () => {
it('handles empty array', () => {
Expand Down Expand Up @@ -62,3 +63,99 @@ describe('allSettled', () => {
]);
});
});

describe('deepCompare', () => {
const base: UserTraits = {
age: 30,
address: {
city: 'San Francisco',
country: 'USA',
},
company: {
name: 'Twilio',
},
deepNested: {
level1: {
level2: {
level3: true,
},
},
},
};

it('shallow compare, same object should return true', () => {
const a: UserTraits = { ...base };
const b: UserTraits = a;
expect(deepCompare(a, b)).toBe(true);
});

it('deep compare, object copy should return true', () => {
const a: UserTraits = { ...base };
const b: UserTraits = { ...base };
expect(deepCompare(a, b)).toBe(true);
});

it('deep compare, different key objects should return false', () => {
const a: UserTraits = { ...base };
const b: UserTraits = {
age: 20,
deepNested: {
level1: {
level2: {
level3: false,
},
},
},
};
expect(deepCompare(a, b)).toBe(false);
});

it('deep compare, modified objects should return false', () => {
const a: UserTraits = { ...base };
const b: UserTraits = {
...base,
age: 20,
deepNested: {
level1: {
level2: {
level3: false,
},
},
},
};
expect(deepCompare(a, b)).toBe(false);
});

it('deep compare, different nested objects should return false', () => {
const a: UserTraits = { ...base };
const b: UserTraits = {
...base,
age: 20,
deepNested: {
level1: {
level2: {
level3: true,
},
anotherLevel2: {
level3: true,
},
},
},
};
expect(deepCompare(a, b)).toBe(false);
});

it('deep compare, mistmatching nested object type should return false', () => {
const a: UserTraits = { ...base };
const b: UserTraits = {
...base,
age: 20,
deepNested: {
level1: {
level2: 1,
},
},
};
expect(deepCompare(a, b)).toBe(false);
});
});
1 change: 1 addition & 0 deletions packages/core/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ export {
isDate,
objectToString,
unknownToString,
deepCompare,
} from './util';
export { SegmentClient } from './analytics';
export { SegmentDestination } from './plugins/SegmentDestination';
Expand Down
40 changes: 37 additions & 3 deletions packages/core/src/util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ const sizeOf = (obj: unknown): number => {

export const warnMissingNativeModule = () => {
const MISSING_NATIVE_MODULE_WARNING =
`The package 'analytics-react-native' can't access a custom native module. Make sure: \n\n` +
"The package 'analytics-react-native' can't access a custom native module. Make sure: \n\n" +
Platform.select({ ios: "- You have run 'pod install'\n", default: '' }) +
'- You rebuilt the app after installing the package\n' +
'- You are not using Expo managed workflow\n';
Expand All @@ -18,7 +18,9 @@ export const warnMissingNativeModule = () => {

export const getNativeModule = (moduleName: string) => {
const module = (NativeModules[moduleName] as NativeModule) ?? undefined;
if (module === undefined) warnMissingNativeModule();
if (module === undefined) {
warnMissingNativeModule();
}
return module;
};

Expand Down Expand Up @@ -143,7 +145,6 @@ export function isDate(value: unknown): value is Date {
export function objectToString(value: object, json = true): string | undefined {
// If the object has a custom toString we well use that
if (value.toString !== Object.prototype.toString) {
// eslint-disable-next-line @typescript-eslint/no-base-to-string
return value.toString();
}
if (json) {
Expand Down Expand Up @@ -198,3 +199,36 @@ export const isObject = (value: unknown): value is Record<string, unknown> =>
value !== undefined &&
typeof value === 'object' &&
!Array.isArray(value);

/**
* Utility to deeply compare 2 objects
* @param a unknown object
* @param b unknown object
* @returns true if both objects have the same keys and values
*/
export function deepCompare<T>(a: T, b: T): boolean {
// Shallow compare first, just in case
if (a === b) {
return true;
}

// If not objects then compare values directly
if (!isObject(a) || !isObject(b)) {
return a === b;
}

const keysA = Object.keys(a);
const keysB = Object.keys(b);

if (keysA.length !== keysB.length) {
return false;
}

for (const key of keysA) {
if (!keysB.includes(key) || !deepCompare(a[key], b[key])) {
return false;
}
}

return true;
}
Loading
Loading