From 12bad6ee485e8f101bbba6faf572cb4fb5f85ee9 Mon Sep 17 00:00:00 2001 From: szymonrybczak Date: Wed, 8 May 2024 16:23:35 +0200 Subject: [PATCH 1/3] perf(autolinking)!: prioritise files with `*Package.java|*Package.kt` in `getPackageClassName` --- .../src/config/findPackageClassName.ts | 35 +++++++++++++++---- 1 file changed, 28 insertions(+), 7 deletions(-) diff --git a/packages/cli-platform-android/src/config/findPackageClassName.ts b/packages/cli-platform-android/src/config/findPackageClassName.ts index d2c91d718..39cdd7ff0 100644 --- a/packages/cli-platform-android/src/config/findPackageClassName.ts +++ b/packages/cli-platform-android/src/config/findPackageClassName.ts @@ -11,22 +11,43 @@ import glob from 'fast-glob'; import path from 'path'; import {unixifyPaths} from '@react-native-community/cli-tools'; -export function getMainActivityFiles(folder: string) { - return glob.sync('**/+(*.java|*.kt)', {cwd: unixifyPaths(folder)}); +export function getMainActivityFiles( + folder: string, + includePackage: boolean = true, +) { + let patternArray = []; + + if (includePackage) { + patternArray.push('*Package.java', '*Package.kt'); + } else { + patternArray.push('*.java', '*.kt'); + } + + return glob.sync(`**/+(${patternArray.join('|')})`, { + cwd: unixifyPaths(folder), + }); } export default function getPackageClassName(folder: string) { - const files = getMainActivityFiles(folder); + let files = getMainActivityFiles(folder); + let packages = getClassNameMatches(files, folder); - const packages = files - .map((filePath) => fs.readFileSync(path.join(folder, filePath), 'utf8')) - .map(matchClassName) - .filter((match) => match); + if (!packages.length) { + files = getMainActivityFiles(folder, false); + packages = getClassNameMatches(files, folder); + } // @ts-ignore return packages.length ? packages[0][1] : null; } +function getClassNameMatches(files: string[], folder: string) { + return files + .map((filePath) => fs.readFileSync(path.join(folder, filePath), 'utf8')) + .map(matchClassName) + .filter((match) => match); +} + export function matchClassName(file: string) { const nativeModuleMatch = file.match( /class\s+(\w+[^(\s]*)[\s\w():]*(\s+implements\s+|:)[\s\w():,]*[^{]*ReactPackage/, From 6806649c30c72ba9b0e39feb9cdb7bd9b464bee8 Mon Sep 17 00:00:00 2001 From: szymonrybczak Date: Fri, 10 May 2024 07:39:23 +0200 Subject: [PATCH 2/3] fix: get all files when getting files inside project --- .../cli-platform-android/src/config/isProjectUsingKotlin.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/cli-platform-android/src/config/isProjectUsingKotlin.ts b/packages/cli-platform-android/src/config/isProjectUsingKotlin.ts index a0b7363a0..1d163356f 100644 --- a/packages/cli-platform-android/src/config/isProjectUsingKotlin.ts +++ b/packages/cli-platform-android/src/config/isProjectUsingKotlin.ts @@ -1,7 +1,7 @@ import {getMainActivityFiles} from './findPackageClassName'; export default function isProjectUsingKotlin(sourceDir: string): boolean { - const mainActivityFiles = getMainActivityFiles(sourceDir); + const mainActivityFiles = getMainActivityFiles(sourceDir, false); return mainActivityFiles.some((file) => file.endsWith('.kt')); } From 73e203c9eaf04d7292d5c4177a0ec3f4520299d8 Mon Sep 17 00:00:00 2001 From: szymonrybczak Date: Fri, 7 Jun 2024 14:38:49 +0200 Subject: [PATCH 3/3] test: add tests --- .../src/config/__fixtures__/android.ts | 6 ++++ .../src/config/__fixtures__/files/React.java | 34 +++++++++++++++++++ .../src/config/__fixtures__/files/React.kt | 26 ++++++++++++++ .../__tests__/findPackageClassName.test.ts | 18 ++++++++++ 4 files changed, 84 insertions(+) create mode 100644 packages/cli-platform-android/src/config/__fixtures__/files/React.java create mode 100644 packages/cli-platform-android/src/config/__fixtures__/files/React.kt diff --git a/packages/cli-platform-android/src/config/__fixtures__/android.ts b/packages/cli-platform-android/src/config/__fixtures__/android.ts index 44c2b8f39..f8ba3e141 100644 --- a/packages/cli-platform-android/src/config/__fixtures__/android.ts +++ b/packages/cli-platform-android/src/config/__fixtures__/android.ts @@ -75,6 +75,12 @@ export const valid = generateValidFileStructureForLib('ReactPackage.java'); export const validKotlin = generateValidFileStructureForLib('ReactPackage.kt'); +export const validWithDifferentFileName = + generateValidFileStructureForLib('React.java'); + +export const validKotlinWithDifferentFileName = + generateValidFileStructureForLib('React.kt'); + export const validApp = generateValidFileStructureForApp(); export const userConfigManifest = { diff --git a/packages/cli-platform-android/src/config/__fixtures__/files/React.java b/packages/cli-platform-android/src/config/__fixtures__/files/React.java new file mode 100644 index 000000000..08695ebb7 --- /dev/null +++ b/packages/cli-platform-android/src/config/__fixtures__/files/React.java @@ -0,0 +1,34 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +package com.some.example; + +import com.facebook.react.ReactPackage; +import com.facebook.react.bridge.NativeModule; +import com.facebook.react.bridge.ReactApplicationContext; +import com.facebook.react.uimanager.ViewManager; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +public class SomeExampleJavaPackage implements ReactPackage { + + @Override + public List createNativeModules( + ReactApplicationContext reactContext) { + List modules = new ArrayList<>(); + modules.add(new SomeExampleModule(reactContext)); + return modules; + } + + @Override + public List createViewManagers(ReactApplicationContext reactContext) { + return Collections.emptyList(); + } +} diff --git a/packages/cli-platform-android/src/config/__fixtures__/files/React.kt b/packages/cli-platform-android/src/config/__fixtures__/files/React.kt new file mode 100644 index 000000000..17b0db22b --- /dev/null +++ b/packages/cli-platform-android/src/config/__fixtures__/files/React.kt @@ -0,0 +1,26 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +package com.some.example; + +import android.view.View +import com.facebook.react.ReactPackage +import com.facebook.react.bridge.NativeModule +import com.facebook.react.bridge.ReactApplicationContext +import com.facebook.react.uimanager.ReactShadowNode +import com.facebook.react.uimanager.ViewManager +import java.util.* + +class SomeExampleKotlinPackage : ReactPackage { + + override fun createNativeModules(reactContext: ReactApplicationContext): MutableList + = mutableListOf(MaterialPaletteModule(reactContext)) + + override fun createViewManagers(reactContext: ReactApplicationContext?): + MutableList> = Collections.emptyList() + +} diff --git a/packages/cli-platform-android/src/config/__tests__/findPackageClassName.test.ts b/packages/cli-platform-android/src/config/__tests__/findPackageClassName.test.ts index 73ba9283e..99dbd121b 100644 --- a/packages/cli-platform-android/src/config/__tests__/findPackageClassName.test.ts +++ b/packages/cli-platform-android/src/config/__tests__/findPackageClassName.test.ts @@ -24,9 +24,15 @@ const fs = require('fs'); flatJava: { android: mocks.valid, }, + flatJavaDifferentName: { + android: mocks.validWithDifferentFileName, + }, flatKotlin: { android: mocks.validKotlin, }, + flatKotlinDifferentName: { + android: mocks.validKotlinWithDifferentFileName, + }, }, platform, ); @@ -42,12 +48,24 @@ const fs = require('fs'); ); }); + it('returns the name of the java class implementing ReactPackage with different file name', () => { + expect(findPackageClassName(`${root}flatJavaDifferentName`)).toBe( + 'SomeExampleJavaPackage', + ); + }); + it('returns the name of the kotlin class implementing ReactPackage', () => { expect(findPackageClassName(`${root}flatKotlin`)).toBe( 'SomeExampleKotlinPackage', ); }); + it('returns the name of the kotlin class implementing ReactPackage with different file name', () => { + expect(findPackageClassName(`${root}flatKotlinDifferentName`)).toBe( + 'SomeExampleKotlinPackage', + ); + }); + it('returns `null` if there are no matches', () => { expect(findPackageClassName(`${root}empty`)).toBeNull(); });