Skip to content

Commit

Permalink
perf(autolinking)!: prioritise files with *Package.java|*Package.kt
Browse files Browse the repository at this point in the history
… in `getPackageClassName` (#2384)

* perf(autolinking)!: prioritise files with `*Package.java|*Package.kt` in `getPackageClassName`

* fix: get all files when getting files inside project

* test: add tests
  • Loading branch information
szymonrybczak committed Jun 7, 2024
1 parent 9c813dc commit 1754348
Show file tree
Hide file tree
Showing 6 changed files with 113 additions and 8 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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 = {
Expand Down
Original file line number Diff line number Diff line change
@@ -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<NativeModule> createNativeModules(
ReactApplicationContext reactContext) {
List<NativeModule> modules = new ArrayList<>();
modules.add(new SomeExampleModule(reactContext));
return modules;
}

@Override
public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) {
return Collections.emptyList();
}
}
Original file line number Diff line number Diff line change
@@ -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<NativeModule>
= mutableListOf(MaterialPaletteModule(reactContext))

override fun createViewManagers(reactContext: ReactApplicationContext?):
MutableList<ViewManager<View, ReactShadowNode>> = Collections.emptyList()

}
Original file line number Diff line number Diff line change
Expand Up @@ -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,
);
Expand All @@ -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();
});
Expand Down
35 changes: 28 additions & 7 deletions packages/cli-platform-android/src/config/findPackageClassName.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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/,
Expand Down
Original file line number Diff line number Diff line change
@@ -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'));
}

0 comments on commit 1754348

Please sign in to comment.