expo-modules-autolinking 1.1.2 → 1.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +12 -0
- package/README.md +1 -1
- package/build/ExpoModuleConfig.d.ts +5 -1
- package/build/ExpoModuleConfig.js +6 -0
- package/build/ExpoModuleConfig.js.map +1 -1
- package/build/platforms/android.js +6 -0
- package/build/platforms/android.js.map +1 -1
- package/build/types.d.ts +23 -0
- package/build/types.js.map +1 -1
- package/package.json +2 -2
- package/scripts/android/autolinking_implementation.gradle +58 -5
- package/scripts/ios/autolinking_manager.rb +21 -12
- package/scripts/ios/constants.rb +2 -0
- package/scripts/ios/project_integrator.rb +142 -8
- package/src/ExpoModuleConfig.ts +8 -1
- package/src/platforms/android.ts +9 -0
- package/src/types.ts +28 -0
package/CHANGELOG.md
CHANGED
|
@@ -10,6 +10,18 @@
|
|
|
10
10
|
|
|
11
11
|
### 💡 Others
|
|
12
12
|
|
|
13
|
+
## 1.3.0 — 2023-05-08
|
|
14
|
+
|
|
15
|
+
### 🎉 New features
|
|
16
|
+
|
|
17
|
+
- Generating `ExpoModulesProvider.swift` in the build phase script instead of only `pod install`. ([#21108](https://github.com/expo/expo/pull/21108) by [@tsapeta](https://github.com/tsapeta))
|
|
18
|
+
|
|
19
|
+
## 1.2.0 - 2023-04-13
|
|
20
|
+
|
|
21
|
+
### 🎉 New features
|
|
22
|
+
|
|
23
|
+
- Added Gradle plugin autolinking support for Android. ([#21377](https://github.com/expo/expo/pull/21377) by [@kudo](https://github.com/kudo))
|
|
24
|
+
|
|
13
25
|
## 1.1.2 — 2023-02-14
|
|
14
26
|
|
|
15
27
|
### 💡 Others
|
package/README.md
CHANGED
|
@@ -16,7 +16,7 @@ Scripts that autolink Expo modules.
|
|
|
16
16
|
|
|
17
17
|
# Installation in managed Expo projects
|
|
18
18
|
|
|
19
|
-
For [managed](https://docs.expo.dev/
|
|
19
|
+
For [managed](https://docs.expo.dev/archive/managed-vs-bare/) Expo projects, please follow the installation instructions in the [API documentation for the latest stable release](#api-documentation). If you follow the link and there is no documentation available then this library is not yet usable within managed projects — it is likely to be included in an upcoming Expo SDK release.
|
|
20
20
|
|
|
21
21
|
# Installation in bare React Native projects
|
|
22
22
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { RawExpoModuleConfig, SupportedPlatform } from './types';
|
|
1
|
+
import { AndroidGradlePluginDescriptor, RawExpoModuleConfig, SupportedPlatform } from './types';
|
|
2
2
|
/**
|
|
3
3
|
* A class that wraps the raw config (`expo-module.json` or `unimodule.json`).
|
|
4
4
|
*/
|
|
@@ -41,6 +41,10 @@ export declare class ExpoModuleConfig {
|
|
|
41
41
|
* Returns build.gradle file paths defined by the module author.
|
|
42
42
|
*/
|
|
43
43
|
androidGradlePaths(): string[];
|
|
44
|
+
/**
|
|
45
|
+
* Returns gradle plugins descriptors defined by the module author.
|
|
46
|
+
*/
|
|
47
|
+
androidGradlePlugins(): AndroidGradlePluginDescriptor[];
|
|
44
48
|
/**
|
|
45
49
|
* Returns serializable raw config.
|
|
46
50
|
*/
|
|
@@ -72,6 +72,12 @@ class ExpoModuleConfig {
|
|
|
72
72
|
androidGradlePaths() {
|
|
73
73
|
return arrayize(this.rawConfig.android?.gradlePath ?? []);
|
|
74
74
|
}
|
|
75
|
+
/**
|
|
76
|
+
* Returns gradle plugins descriptors defined by the module author.
|
|
77
|
+
*/
|
|
78
|
+
androidGradlePlugins() {
|
|
79
|
+
return arrayize(this.rawConfig.android?.gradlePlugins ?? []);
|
|
80
|
+
}
|
|
75
81
|
/**
|
|
76
82
|
* Returns serializable raw config.
|
|
77
83
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ExpoModuleConfig.js","sourceRoot":"","sources":["../src/ExpoModuleConfig.ts"],"names":[],"mappings":";;;AAEA,SAAS,QAAQ,CAAI,KAA0B;IAC7C,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE;QACxB,OAAO,KAAK,CAAC;KACd;IACD,OAAO,KAAK,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;AACtC,CAAC;AAED;;GAEG;AACH,MAAa,gBAAgB;IAC3B,YAAqB,SAA8B;QAA9B,cAAS,GAAT,SAAS,CAAqB;IAAG,CAAC;IAEvD;;OAEG;IACH,gBAAgB,CAAC,QAA2B;QAC1C,OAAO,IAAI,CAAC,SAAS,CAAC,SAAS,EAAE,QAAQ,CAAC,QAAQ,CAAC,IAAI,KAAK,CAAC;IAC/D,CAAC;IAED;;OAEG;IACH,UAAU;QACR,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC;QAErC,4DAA4D;QAC5D,OAAO,SAAS,EAAE,OAAO,IAAI,SAAS,EAAE,iBAAiB,IAAI,EAAE,CAAC;IAClE,CAAC;IAED;;OAEG;IACH,yBAAyB;QACvB,OAAO,IAAI,CAAC,SAAS,CAAC,GAAG,EAAE,sBAAsB,IAAI,EAAE,CAAC;IAC1D,CAAC;IAED;;OAEG;IACH,wBAAwB;QACtB,OAAO,IAAI,CAAC,SAAS,CAAC,GAAG,EAAE,qBAAqB,IAAI,EAAE,CAAC;IACzD,CAAC;IAED;;OAEG;IACH,eAAe;QACb,OAAO,QAAQ,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,EAAE,WAAW,CAAC,CAAC;IACnD,CAAC;IAED;;OAEG;IACH,mBAAmB;QACjB,OAAO,QAAQ,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,EAAE,eAAe,CAAC,CAAC;IACvD,CAAC;IAED;;OAEG;IACH,YAAY;QACV,OAAO,IAAI,CAAC,SAAS,CAAC,GAAG,EAAE,SAAS,IAAI,KAAK,CAAC;IAChD,CAAC;IAED;;OAEG;IACH,cAAc;QACZ,MAAM,aAAa,GAAG,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC;QAE7C,4DAA4D;QAC5D,OAAO,aAAa,EAAE,OAAO,IAAI,aAAa,EAAE,iBAAiB,IAAI,EAAE,CAAC;IAC1E,CAAC;IAED;;OAEG;IACH,kBAAkB;QAChB,OAAO,QAAQ,CAAC,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,UAAU,IAAI,EAAE,CAAC,CAAC;IAC5D,CAAC;IAED;;OAEG;IACH,MAAM;QACJ,OAAO,IAAI,CAAC,SAAS,CAAC;IACxB,CAAC;CACF;
|
|
1
|
+
{"version":3,"file":"ExpoModuleConfig.js","sourceRoot":"","sources":["../src/ExpoModuleConfig.ts"],"names":[],"mappings":";;;AAEA,SAAS,QAAQ,CAAI,KAA0B;IAC7C,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE;QACxB,OAAO,KAAK,CAAC;KACd;IACD,OAAO,KAAK,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;AACtC,CAAC;AAED;;GAEG;AACH,MAAa,gBAAgB;IAC3B,YAAqB,SAA8B;QAA9B,cAAS,GAAT,SAAS,CAAqB;IAAG,CAAC;IAEvD;;OAEG;IACH,gBAAgB,CAAC,QAA2B;QAC1C,OAAO,IAAI,CAAC,SAAS,CAAC,SAAS,EAAE,QAAQ,CAAC,QAAQ,CAAC,IAAI,KAAK,CAAC;IAC/D,CAAC;IAED;;OAEG;IACH,UAAU;QACR,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC;QAErC,4DAA4D;QAC5D,OAAO,SAAS,EAAE,OAAO,IAAI,SAAS,EAAE,iBAAiB,IAAI,EAAE,CAAC;IAClE,CAAC;IAED;;OAEG;IACH,yBAAyB;QACvB,OAAO,IAAI,CAAC,SAAS,CAAC,GAAG,EAAE,sBAAsB,IAAI,EAAE,CAAC;IAC1D,CAAC;IAED;;OAEG;IACH,wBAAwB;QACtB,OAAO,IAAI,CAAC,SAAS,CAAC,GAAG,EAAE,qBAAqB,IAAI,EAAE,CAAC;IACzD,CAAC;IAED;;OAEG;IACH,eAAe;QACb,OAAO,QAAQ,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,EAAE,WAAW,CAAC,CAAC;IACnD,CAAC;IAED;;OAEG;IACH,mBAAmB;QACjB,OAAO,QAAQ,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,EAAE,eAAe,CAAC,CAAC;IACvD,CAAC;IAED;;OAEG;IACH,YAAY;QACV,OAAO,IAAI,CAAC,SAAS,CAAC,GAAG,EAAE,SAAS,IAAI,KAAK,CAAC;IAChD,CAAC;IAED;;OAEG;IACH,cAAc;QACZ,MAAM,aAAa,GAAG,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC;QAE7C,4DAA4D;QAC5D,OAAO,aAAa,EAAE,OAAO,IAAI,aAAa,EAAE,iBAAiB,IAAI,EAAE,CAAC;IAC1E,CAAC;IAED;;OAEG;IACH,kBAAkB;QAChB,OAAO,QAAQ,CAAC,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,UAAU,IAAI,EAAE,CAAC,CAAC;IAC5D,CAAC;IAED;;OAEG;IACH,oBAAoB;QAClB,OAAO,QAAQ,CAAC,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,aAAa,IAAI,EAAE,CAAC,CAAC;IAC/D,CAAC;IAED;;OAEG;IACH,MAAM;QACJ,OAAO,IAAI,CAAC,SAAS,CAAC;IACxB,CAAC;CACF;AArFD,4CAqFC;AAED;;GAEG;AACH,SAAgB,iCAAiC,CAAC,IAAY;IAC5D,kDAAkD;IAClD,4DAA4D;IAC5D,OAAO,IAAI,gBAAgB,CAAC,OAAO,CAAC,IAAI,CAAwB,CAAC,CAAC;AACpE,CAAC;AAJD,8EAIC","sourcesContent":["import { AndroidGradlePluginDescriptor, RawExpoModuleConfig, SupportedPlatform } from './types';\n\nfunction arrayize<T>(value: T[] | T | undefined): T[] {\n if (Array.isArray(value)) {\n return value;\n }\n return value != null ? [value] : [];\n}\n\n/**\n * A class that wraps the raw config (`expo-module.json` or `unimodule.json`).\n */\nexport class ExpoModuleConfig {\n constructor(readonly rawConfig: RawExpoModuleConfig) {}\n\n /**\n * Whether the module supports given platform.\n */\n supportsPlatform(platform: SupportedPlatform): boolean {\n return this.rawConfig.platforms?.includes(platform) ?? false;\n }\n\n /**\n * Returns a list of names of Swift native modules classes to put to the generated modules provider file.\n */\n iosModules() {\n const iosConfig = this.rawConfig.ios;\n\n // `modulesClassNames` is a legacy name for the same config.\n return iosConfig?.modules ?? iosConfig?.modulesClassNames ?? [];\n }\n\n /**\n * Returns a list of names of Swift classes that receives AppDelegate life-cycle events.\n */\n iosAppDelegateSubscribers(): string[] {\n return this.rawConfig.ios?.appDelegateSubscribers ?? [];\n }\n\n /**\n * Returns a list of names of Swift classes that implement `ExpoReactDelegateHandler`.\n */\n iosReactDelegateHandlers(): string[] {\n return this.rawConfig.ios?.reactDelegateHandlers ?? [];\n }\n\n /**\n * Returns podspec paths defined by the module author.\n */\n iosPodspecPaths(): string[] {\n return arrayize(this.rawConfig.ios?.podspecPath);\n }\n\n /**\n * Returns the product module names, if defined by the module author.\n */\n iosSwiftModuleNames(): string[] {\n return arrayize(this.rawConfig.ios?.swiftModuleName);\n }\n\n /**\n * Returns whether this module will be added only to the debug configuration\n */\n iosDebugOnly(): boolean {\n return this.rawConfig.ios?.debugOnly ?? false;\n }\n\n /**\n * Returns a list of names of Kotlin native modules classes to put to the generated package provider file.\n */\n androidModules() {\n const androidConfig = this.rawConfig.android;\n\n // `modulesClassNames` is a legacy name for the same config.\n return androidConfig?.modules ?? androidConfig?.modulesClassNames ?? [];\n }\n\n /**\n * Returns build.gradle file paths defined by the module author.\n */\n androidGradlePaths(): string[] {\n return arrayize(this.rawConfig.android?.gradlePath ?? []);\n }\n\n /**\n * Returns gradle plugins descriptors defined by the module author.\n */\n androidGradlePlugins(): AndroidGradlePluginDescriptor[] {\n return arrayize(this.rawConfig.android?.gradlePlugins ?? []);\n }\n\n /**\n * Returns serializable raw config.\n */\n toJSON(): RawExpoModuleConfig {\n return this.rawConfig;\n }\n}\n\n/**\n * Reads the config at given path and returns the config wrapped by `ExpoModuleConfig` class.\n */\nexport function requireAndResolveExpoModuleConfig(path: string): ExpoModuleConfig {\n // TODO: Validate the raw config against a schema.\n // TODO: Support for `*.js` files, not only static `*.json`.\n return new ExpoModuleConfig(require(path) as RawExpoModuleConfig);\n}\n"]}
|
|
@@ -44,9 +44,15 @@ async function resolveModuleAsync(packageName, revision) {
|
|
|
44
44
|
sourceDir: path_1.default.dirname(gradleFilePath),
|
|
45
45
|
};
|
|
46
46
|
});
|
|
47
|
+
const plugins = (revision.config?.androidGradlePlugins() ?? []).map(({ id, group, sourceDir }) => ({
|
|
48
|
+
id,
|
|
49
|
+
group,
|
|
50
|
+
sourceDir: path_1.default.join(revision.path, sourceDir),
|
|
51
|
+
}));
|
|
47
52
|
return {
|
|
48
53
|
packageName,
|
|
49
54
|
projects,
|
|
55
|
+
...(plugins.length > 0 ? { plugins } : {}),
|
|
50
56
|
modules: revision.config?.androidModules() ?? [],
|
|
51
57
|
};
|
|
52
58
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"android.js","sourceRoot":"","sources":["../../src/platforms/android.ts"],"names":[],"mappings":"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","sourcesContent":["import glob from 'fast-glob';\nimport fs from 'fs-extra';\nimport path from 'path';\n\nimport { ModuleDescriptorAndroid, PackageRevision } from '../types';\n\n/**\n * Generates Java file that contains all autolinked packages.\n */\nexport async function generatePackageListAsync(\n modules: ModuleDescriptorAndroid[],\n targetPath: string,\n namespace: string\n): Promise<void> {\n const generatedFileContent = await generatePackageListFileContentAsync(modules, namespace);\n await fs.outputFile(targetPath, generatedFileContent);\n}\n\nasync function findGradleFilesAsync(revision: PackageRevision): Promise<string[]> {\n const configGradlePaths = revision.config?.androidGradlePaths();\n if (configGradlePaths && configGradlePaths.length) {\n return configGradlePaths;\n }\n\n const buildGradleFiles = await glob('*/build.gradle', {\n cwd: revision.path,\n ignore: ['**/node_modules/**'],\n });\n\n return buildGradleFiles;\n}\n\nexport async function resolveModuleAsync(\n packageName: string,\n revision: PackageRevision\n): Promise<ModuleDescriptorAndroid | null> {\n // TODO: Relative source dir should be configurable through the module config.\n\n // Don't link itself... :D\n if (packageName === '@unimodules/react-native-adapter') {\n return null;\n }\n\n const buildGradleFiles = await findGradleFilesAsync(revision);\n // Just in case where the module doesn't have its own `build.gradle`.\n if (!buildGradleFiles.length) {\n return null;\n }\n\n const projects = buildGradleFiles.map((buildGradleFile) => {\n const gradleFilePath = path.join(revision.path, buildGradleFile);\n return {\n name: convertPackageNameToProjectName(\n packageName,\n path.relative(revision.path, gradleFilePath)\n ),\n sourceDir: path.dirname(gradleFilePath),\n };\n });\n\n return {\n packageName,\n projects,\n modules: revision.config?.androidModules() ?? [],\n };\n}\n\n/**\n * Generates the string to put into the generated package list.\n */\nasync function generatePackageListFileContentAsync(\n modules: ModuleDescriptorAndroid[],\n namespace: string\n): Promise<string> {\n // TODO: Instead of ignoring `expo` here, make the package class paths configurable from `expo-module.config.json`.\n const packagesClasses = await findAndroidPackagesAsync(\n modules.filter((module) => module.packageName !== 'expo')\n );\n\n const modulesClasses = await findAndroidModules(modules);\n\n return `package ${namespace};\n\nimport java.util.Arrays;\nimport java.util.List;\nimport expo.modules.core.interfaces.Package;\nimport expo.modules.kotlin.modules.Module;\nimport expo.modules.kotlin.ModulesProvider;\n\npublic class ExpoModulesPackageList implements ModulesProvider {\n private static class LazyHolder {\n static final List<Package> packagesList = Arrays.<Package>asList(\n${packagesClasses.map((packageClass) => ` new ${packageClass}()`).join(',\\n')}\n );\n\n static final List<Class<? extends Module>> modulesList = Arrays.<Class<? extends Module>>asList(\n ${modulesClasses.map((moduleClass) => ` ${moduleClass}.class`).join(',\\n')}\n );\n }\n\n public static List<Package> getPackageList() {\n return LazyHolder.packagesList;\n }\n\n @Override\n public List<Class<? extends Module>> getModulesList() {\n return LazyHolder.modulesList;\n }\n}\n`;\n}\n\nfunction findAndroidModules(modules: ModuleDescriptorAndroid[]): string[] {\n const modulesToProvide = modules.filter((module) => module.modules.length > 0);\n const classNames = ([] as string[]).concat(...modulesToProvide.map((module) => module.modules));\n return classNames;\n}\n\nasync function findAndroidPackagesAsync(modules: ModuleDescriptorAndroid[]): Promise<string[]> {\n const classes: string[] = [];\n\n const flattenedSourceDirList: string[] = [];\n for (const module of modules) {\n for (const project of module.projects) {\n flattenedSourceDirList.push(project.sourceDir);\n }\n }\n\n await Promise.all(\n flattenedSourceDirList.map(async (sourceDir) => {\n const files = await glob('**/*Package.{java,kt}', {\n cwd: sourceDir,\n });\n\n for (const file of files) {\n const fileContent = await fs.readFile(path.join(sourceDir, file), 'utf8');\n\n const packageRegex = (() => {\n if (process.env.EXPO_SHOULD_USE_LEGACY_PACKAGE_INTERFACE) {\n return /\\bimport\\s+org\\.unimodules\\.core\\.(interfaces\\.Package|BasePackage)\\b/;\n } else {\n return /\\bimport\\s+expo\\.modules\\.core\\.(interfaces\\.Package|BasePackage)\\b/;\n }\n })();\n\n // Very naive check to skip non-expo packages\n if (!packageRegex.test(fileContent)) {\n continue;\n }\n\n const classPathMatches = fileContent.match(/^package ([\\w.]+)\\b/m);\n\n if (classPathMatches) {\n const basename = path.basename(file, path.extname(file));\n classes.push(`${classPathMatches[1]}.${basename}`);\n }\n }\n })\n );\n return classes.sort();\n}\n\n/**\n * Converts the package name and gradle file path to Android's project name.\n * `$` to indicate subprojects\n * `/` path will transform as `-`\n *\n * Example: `@expo/example` + `android/build.gradle` → `expo-example`\n *\n * Example: multiple projects\n * - `expo-test` + `android/build.gradle` → `react-native-third-party`\n * - `expo-test` + `subproject/build.gradle` → `react-native-third-party$subproject`\n */\nexport function convertPackageNameToProjectName(\n packageName: string,\n buildGradleFile: string\n): string {\n const name = packageName.replace(/^@/g, '').replace(/\\W+/g, '-');\n const baseDir = path.dirname(buildGradleFile).replace(/\\//g, '-');\n return baseDir === 'android' ? name : `${name}$${baseDir}`;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"android.js","sourceRoot":"","sources":["../../src/platforms/android.ts"],"names":[],"mappings":";;;;;;AAAA,0DAA6B;AAC7B,wDAA0B;AAC1B,gDAAwB;AAIxB;;GAEG;AACI,KAAK,UAAU,wBAAwB,CAC5C,OAAkC,EAClC,UAAkB,EAClB,SAAiB;IAEjB,MAAM,oBAAoB,GAAG,MAAM,mCAAmC,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC;IAC3F,MAAM,kBAAE,CAAC,UAAU,CAAC,UAAU,EAAE,oBAAoB,CAAC,CAAC;AACxD,CAAC;AAPD,4DAOC;AAED,KAAK,UAAU,oBAAoB,CAAC,QAAyB;IAC3D,MAAM,iBAAiB,GAAG,QAAQ,CAAC,MAAM,EAAE,kBAAkB,EAAE,CAAC;IAChE,IAAI,iBAAiB,IAAI,iBAAiB,CAAC,MAAM,EAAE;QACjD,OAAO,iBAAiB,CAAC;KAC1B;IAED,MAAM,gBAAgB,GAAG,MAAM,IAAA,mBAAI,EAAC,gBAAgB,EAAE;QACpD,GAAG,EAAE,QAAQ,CAAC,IAAI;QAClB,MAAM,EAAE,CAAC,oBAAoB,CAAC;KAC/B,CAAC,CAAC;IAEH,OAAO,gBAAgB,CAAC;AAC1B,CAAC;AAEM,KAAK,UAAU,kBAAkB,CACtC,WAAmB,EACnB,QAAyB;IAEzB,8EAA8E;IAE9E,0BAA0B;IAC1B,IAAI,WAAW,KAAK,kCAAkC,EAAE;QACtD,OAAO,IAAI,CAAC;KACb;IAED,MAAM,gBAAgB,GAAG,MAAM,oBAAoB,CAAC,QAAQ,CAAC,CAAC;IAC9D,qEAAqE;IACrE,IAAI,CAAC,gBAAgB,CAAC,MAAM,EAAE;QAC5B,OAAO,IAAI,CAAC;KACb;IAED,MAAM,QAAQ,GAAG,gBAAgB,CAAC,GAAG,CAAC,CAAC,eAAe,EAAE,EAAE;QACxD,MAAM,cAAc,GAAG,cAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,eAAe,CAAC,CAAC;QACjE,OAAO;YACL,IAAI,EAAE,+BAA+B,CACnC,WAAW,EACX,cAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,EAAE,cAAc,CAAC,CAC7C;YACD,SAAS,EAAE,cAAI,CAAC,OAAO,CAAC,cAAc,CAAC;SACxC,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,MAAM,OAAO,GAAG,CAAC,QAAQ,CAAC,MAAM,EAAE,oBAAoB,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,CACjE,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE,EAAE,EAAE,CAAC,CAAC;QAC7B,EAAE;QACF,KAAK;QACL,SAAS,EAAE,cAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC;KAC/C,CAAC,CACH,CAAC;IAEF,OAAO;QACL,WAAW;QACX,QAAQ;QACR,GAAG,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC1C,OAAO,EAAE,QAAQ,CAAC,MAAM,EAAE,cAAc,EAAE,IAAI,EAAE;KACjD,CAAC;AACJ,CAAC;AA1CD,gDA0CC;AAED;;GAEG;AACH,KAAK,UAAU,mCAAmC,CAChD,OAAkC,EAClC,SAAiB;IAEjB,mHAAmH;IACnH,MAAM,eAAe,GAAG,MAAM,wBAAwB,CACpD,OAAO,CAAC,MAAM,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,WAAW,KAAK,MAAM,CAAC,CAC1D,CAAC;IAEF,MAAM,cAAc,GAAG,MAAM,kBAAkB,CAAC,OAAO,CAAC,CAAC;IAEzD,OAAO,WAAW,SAAS;;;;;;;;;;;EAW3B,eAAe,CAAC,GAAG,CAAC,CAAC,YAAY,EAAE,EAAE,CAAC,aAAa,YAAY,IAAI,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC;;;;QAI1E,cAAc,CAAC,GAAG,CAAC,CAAC,WAAW,EAAE,EAAE,CAAC,SAAS,WAAW,QAAQ,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC;;;;;;;;;;;;;CAapF,CAAC;AACF,CAAC;AAED,SAAS,kBAAkB,CAAC,OAAkC;IAC5D,MAAM,gBAAgB,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IAC/E,MAAM,UAAU,GAAI,EAAe,CAAC,MAAM,CAAC,GAAG,gBAAgB,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC;IAChG,OAAO,UAAU,CAAC;AACpB,CAAC;AAED,KAAK,UAAU,wBAAwB,CAAC,OAAkC;IACxE,MAAM,OAAO,GAAa,EAAE,CAAC;IAE7B,MAAM,sBAAsB,GAAa,EAAE,CAAC;IAC5C,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE;QAC5B,KAAK,MAAM,OAAO,IAAI,MAAM,CAAC,QAAQ,EAAE;YACrC,sBAAsB,CAAC,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;SAChD;KACF;IAED,MAAM,OAAO,CAAC,GAAG,CACf,sBAAsB,CAAC,GAAG,CAAC,KAAK,EAAE,SAAS,EAAE,EAAE;QAC7C,MAAM,KAAK,GAAG,MAAM,IAAA,mBAAI,EAAC,uBAAuB,EAAE;YAChD,GAAG,EAAE,SAAS;SACf,CAAC,CAAC;QAEH,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE;YACxB,MAAM,WAAW,GAAG,MAAM,kBAAE,CAAC,QAAQ,CAAC,cAAI,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,CAAC;YAE1E,MAAM,YAAY,GAAG,CAAC,GAAG,EAAE;gBACzB,IAAI,OAAO,CAAC,GAAG,CAAC,wCAAwC,EAAE;oBACxD,OAAO,uEAAuE,CAAC;iBAChF;qBAAM;oBACL,OAAO,qEAAqE,CAAC;iBAC9E;YACH,CAAC,CAAC,EAAE,CAAC;YAEL,6CAA6C;YAC7C,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,WAAW,CAAC,EAAE;gBACnC,SAAS;aACV;YAED,MAAM,gBAAgB,GAAG,WAAW,CAAC,KAAK,CAAC,sBAAsB,CAAC,CAAC;YAEnE,IAAI,gBAAgB,EAAE;gBACpB,MAAM,QAAQ,GAAG,cAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,cAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;gBACzD,OAAO,CAAC,IAAI,CAAC,GAAG,gBAAgB,CAAC,CAAC,CAAC,IAAI,QAAQ,EAAE,CAAC,CAAC;aACpD;SACF;IACH,CAAC,CAAC,CACH,CAAC;IACF,OAAO,OAAO,CAAC,IAAI,EAAE,CAAC;AACxB,CAAC;AAED;;;;;;;;;;GAUG;AACH,SAAgB,+BAA+B,CAC7C,WAAmB,EACnB,eAAuB;IAEvB,MAAM,IAAI,GAAG,WAAW,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IACjE,MAAM,OAAO,GAAG,cAAI,CAAC,OAAO,CAAC,eAAe,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;IAClE,OAAO,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,IAAI,IAAI,OAAO,EAAE,CAAC;AAC7D,CAAC;AAPD,0EAOC","sourcesContent":["import glob from 'fast-glob';\nimport fs from 'fs-extra';\nimport path from 'path';\n\nimport { ModuleDescriptorAndroid, PackageRevision } from '../types';\n\n/**\n * Generates Java file that contains all autolinked packages.\n */\nexport async function generatePackageListAsync(\n modules: ModuleDescriptorAndroid[],\n targetPath: string,\n namespace: string\n): Promise<void> {\n const generatedFileContent = await generatePackageListFileContentAsync(modules, namespace);\n await fs.outputFile(targetPath, generatedFileContent);\n}\n\nasync function findGradleFilesAsync(revision: PackageRevision): Promise<string[]> {\n const configGradlePaths = revision.config?.androidGradlePaths();\n if (configGradlePaths && configGradlePaths.length) {\n return configGradlePaths;\n }\n\n const buildGradleFiles = await glob('*/build.gradle', {\n cwd: revision.path,\n ignore: ['**/node_modules/**'],\n });\n\n return buildGradleFiles;\n}\n\nexport async function resolveModuleAsync(\n packageName: string,\n revision: PackageRevision\n): Promise<ModuleDescriptorAndroid | null> {\n // TODO: Relative source dir should be configurable through the module config.\n\n // Don't link itself... :D\n if (packageName === '@unimodules/react-native-adapter') {\n return null;\n }\n\n const buildGradleFiles = await findGradleFilesAsync(revision);\n // Just in case where the module doesn't have its own `build.gradle`.\n if (!buildGradleFiles.length) {\n return null;\n }\n\n const projects = buildGradleFiles.map((buildGradleFile) => {\n const gradleFilePath = path.join(revision.path, buildGradleFile);\n return {\n name: convertPackageNameToProjectName(\n packageName,\n path.relative(revision.path, gradleFilePath)\n ),\n sourceDir: path.dirname(gradleFilePath),\n };\n });\n\n const plugins = (revision.config?.androidGradlePlugins() ?? []).map(\n ({ id, group, sourceDir }) => ({\n id,\n group,\n sourceDir: path.join(revision.path, sourceDir),\n })\n );\n\n return {\n packageName,\n projects,\n ...(plugins.length > 0 ? { plugins } : {}),\n modules: revision.config?.androidModules() ?? [],\n };\n}\n\n/**\n * Generates the string to put into the generated package list.\n */\nasync function generatePackageListFileContentAsync(\n modules: ModuleDescriptorAndroid[],\n namespace: string\n): Promise<string> {\n // TODO: Instead of ignoring `expo` here, make the package class paths configurable from `expo-module.config.json`.\n const packagesClasses = await findAndroidPackagesAsync(\n modules.filter((module) => module.packageName !== 'expo')\n );\n\n const modulesClasses = await findAndroidModules(modules);\n\n return `package ${namespace};\n\nimport java.util.Arrays;\nimport java.util.List;\nimport expo.modules.core.interfaces.Package;\nimport expo.modules.kotlin.modules.Module;\nimport expo.modules.kotlin.ModulesProvider;\n\npublic class ExpoModulesPackageList implements ModulesProvider {\n private static class LazyHolder {\n static final List<Package> packagesList = Arrays.<Package>asList(\n${packagesClasses.map((packageClass) => ` new ${packageClass}()`).join(',\\n')}\n );\n\n static final List<Class<? extends Module>> modulesList = Arrays.<Class<? extends Module>>asList(\n ${modulesClasses.map((moduleClass) => ` ${moduleClass}.class`).join(',\\n')}\n );\n }\n\n public static List<Package> getPackageList() {\n return LazyHolder.packagesList;\n }\n\n @Override\n public List<Class<? extends Module>> getModulesList() {\n return LazyHolder.modulesList;\n }\n}\n`;\n}\n\nfunction findAndroidModules(modules: ModuleDescriptorAndroid[]): string[] {\n const modulesToProvide = modules.filter((module) => module.modules.length > 0);\n const classNames = ([] as string[]).concat(...modulesToProvide.map((module) => module.modules));\n return classNames;\n}\n\nasync function findAndroidPackagesAsync(modules: ModuleDescriptorAndroid[]): Promise<string[]> {\n const classes: string[] = [];\n\n const flattenedSourceDirList: string[] = [];\n for (const module of modules) {\n for (const project of module.projects) {\n flattenedSourceDirList.push(project.sourceDir);\n }\n }\n\n await Promise.all(\n flattenedSourceDirList.map(async (sourceDir) => {\n const files = await glob('**/*Package.{java,kt}', {\n cwd: sourceDir,\n });\n\n for (const file of files) {\n const fileContent = await fs.readFile(path.join(sourceDir, file), 'utf8');\n\n const packageRegex = (() => {\n if (process.env.EXPO_SHOULD_USE_LEGACY_PACKAGE_INTERFACE) {\n return /\\bimport\\s+org\\.unimodules\\.core\\.(interfaces\\.Package|BasePackage)\\b/;\n } else {\n return /\\bimport\\s+expo\\.modules\\.core\\.(interfaces\\.Package|BasePackage)\\b/;\n }\n })();\n\n // Very naive check to skip non-expo packages\n if (!packageRegex.test(fileContent)) {\n continue;\n }\n\n const classPathMatches = fileContent.match(/^package ([\\w.]+)\\b/m);\n\n if (classPathMatches) {\n const basename = path.basename(file, path.extname(file));\n classes.push(`${classPathMatches[1]}.${basename}`);\n }\n }\n })\n );\n return classes.sort();\n}\n\n/**\n * Converts the package name and gradle file path to Android's project name.\n * `$` to indicate subprojects\n * `/` path will transform as `-`\n *\n * Example: `@expo/example` + `android/build.gradle` → `expo-example`\n *\n * Example: multiple projects\n * - `expo-test` + `android/build.gradle` → `react-native-third-party`\n * - `expo-test` + `subproject/build.gradle` → `react-native-third-party$subproject`\n */\nexport function convertPackageNameToProjectName(\n packageName: string,\n buildGradleFile: string\n): string {\n const name = packageName.replace(/^@/g, '').replace(/\\W+/g, '-');\n const baseDir = path.dirname(buildGradleFile).replace(/\\//g, '-');\n return baseDir === 'android' ? name : `${name}$${baseDir}`;\n}\n"]}
|
package/build/types.d.ts
CHANGED
|
@@ -34,9 +34,14 @@ export interface ModuleAndroidProjectInfo {
|
|
|
34
34
|
name: string;
|
|
35
35
|
sourceDir: string;
|
|
36
36
|
}
|
|
37
|
+
export interface ModuleAndroidPluginInfo {
|
|
38
|
+
id: string;
|
|
39
|
+
sourceDir: string;
|
|
40
|
+
}
|
|
37
41
|
export interface ModuleDescriptorAndroid {
|
|
38
42
|
packageName: string;
|
|
39
43
|
projects: ModuleAndroidProjectInfo[];
|
|
44
|
+
plugins?: ModuleAndroidPluginInfo[];
|
|
40
45
|
modules: string[];
|
|
41
46
|
}
|
|
42
47
|
export interface ModuleIosPodspecInfo {
|
|
@@ -54,6 +59,20 @@ export interface ModuleDescriptorIos {
|
|
|
54
59
|
debugOnly: boolean;
|
|
55
60
|
}
|
|
56
61
|
export type ModuleDescriptor = ModuleDescriptorAndroid | ModuleDescriptorIos;
|
|
62
|
+
export interface AndroidGradlePluginDescriptor {
|
|
63
|
+
/**
|
|
64
|
+
* Gradle plugin ID
|
|
65
|
+
*/
|
|
66
|
+
id: string;
|
|
67
|
+
/**
|
|
68
|
+
* Artifact group
|
|
69
|
+
*/
|
|
70
|
+
group: string;
|
|
71
|
+
/**
|
|
72
|
+
* Relative path to the gradle plugin directory
|
|
73
|
+
*/
|
|
74
|
+
sourceDir: string;
|
|
75
|
+
}
|
|
57
76
|
/**
|
|
58
77
|
* Represents a raw config from `expo-module.json`.
|
|
59
78
|
*/
|
|
@@ -117,5 +136,9 @@ export interface RawExpoModuleConfig {
|
|
|
117
136
|
* To have multiple build.gradle projects, string array type is also supported.
|
|
118
137
|
*/
|
|
119
138
|
gradlePath?: string | string[];
|
|
139
|
+
/**
|
|
140
|
+
* Gradle plugins.
|
|
141
|
+
*/
|
|
142
|
+
gradlePlugins?: AndroidGradlePluginDescriptor[];
|
|
120
143
|
};
|
|
121
144
|
}
|
package/build/types.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"","sourcesContent":["import { ExpoModuleConfig } from './ExpoModuleConfig';\n\nexport type SupportedPlatform = 'ios' | 'android' | 'web';\n\nexport interface SearchOptions {\n // Available in the CLI\n searchPaths: string[];\n ignorePaths?: string[] | null;\n exclude?: string[] | null;\n platform: SupportedPlatform;\n silent?: boolean;\n nativeModulesDir?: string | null;\n\n // Scratched from project's config\n flags?: Record<string, any>;\n}\n\nexport interface ResolveOptions extends SearchOptions {\n json?: boolean;\n}\n\nexport interface GenerateOptions extends ResolveOptions {\n target: string;\n namespace?: string;\n empty?: boolean;\n}\n\nexport interface PatchReactImportsOptions {\n podsRoot: string;\n dryRun: boolean;\n}\n\nexport type PackageRevision = {\n path: string;\n version: string;\n config?: ExpoModuleConfig;\n duplicates?: PackageRevision[];\n};\n\nexport type SearchResults = {\n [moduleName: string]: PackageRevision;\n};\n\nexport interface ModuleAndroidProjectInfo {\n name: string;\n sourceDir: string;\n}\n\nexport interface ModuleDescriptorAndroid {\n packageName: string;\n projects: ModuleAndroidProjectInfo[];\n modules: string[];\n}\n\nexport interface ModuleIosPodspecInfo {\n podName: string;\n podspecDir: string;\n}\nexport interface ModuleDescriptorIos {\n packageName: string;\n pods: ModuleIosPodspecInfo[];\n flags: Record<string, any> | undefined;\n swiftModuleNames: string[];\n modules: string[];\n appDelegateSubscribers: string[];\n reactDelegateHandlers: string[];\n debugOnly: boolean;\n}\n\nexport type ModuleDescriptor = ModuleDescriptorAndroid | ModuleDescriptorIos;\n\n/**\n * Represents a raw config from `expo-module.json`.\n */\nexport interface RawExpoModuleConfig {\n /**\n * An array of supported platforms.\n */\n platforms?: SupportedPlatform[];\n\n /**\n * iOS-specific config.\n */\n ios?: {\n /**\n * Names of Swift native modules classes to put to the generated modules provider file.\n */\n modules?: string[];\n\n /**\n * Names of Swift native modules classes to put to the generated modules provider file.\n * @deprecated Deprecated in favor of `modules`. Might be removed in the future releases.\n */\n modulesClassNames?: string[];\n\n /**\n * Names of Swift classes that hooks into `ExpoAppDelegate` to receive AppDelegate life-cycle events.\n */\n appDelegateSubscribers?: string[];\n\n /**\n * Names of Swift classes that implement `ExpoReactDelegateHandler` to hook React instance creation.\n */\n reactDelegateHandlers?: string[];\n\n /**\n * Podspec relative path.\n * To have multiple podspecs, string array type is also supported.\n */\n podspecPath?: string | string[];\n\n /**\n * Swift product module name. If empty, the pod name is used for Swift imports.\n * To have multiple modules, string array is also supported.\n */\n swiftModuleName?: string | string[];\n\n /**\n * Whether this module will be added only to the debug configuration.\n * Defaults to false.\n */\n debugOnly?: boolean;\n };\n\n /**\n * Android-specific config.\n */\n android?: {\n /**\n * Full names (package + class name) of Kotlin native modules classes to put to the generated package provider file.\n */\n modules?: string[];\n\n /**\n * Full names (package + class name) of Kotlin native modules classes to put to the generated package provider file.\n * @deprecated Deprecated in favor of `modules`. Might be removed in the future releases.\n */\n modulesClassNames?: string[];\n\n /**\n * build.gradle relative path.\n * To have multiple build.gradle projects, string array type is also supported.\n */\n gradlePath?: string | string[];\n };\n}\n"]}
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"","sourcesContent":["import { ExpoModuleConfig } from './ExpoModuleConfig';\n\nexport type SupportedPlatform = 'ios' | 'android' | 'web';\n\nexport interface SearchOptions {\n // Available in the CLI\n searchPaths: string[];\n ignorePaths?: string[] | null;\n exclude?: string[] | null;\n platform: SupportedPlatform;\n silent?: boolean;\n nativeModulesDir?: string | null;\n\n // Scratched from project's config\n flags?: Record<string, any>;\n}\n\nexport interface ResolveOptions extends SearchOptions {\n json?: boolean;\n}\n\nexport interface GenerateOptions extends ResolveOptions {\n target: string;\n namespace?: string;\n empty?: boolean;\n}\n\nexport interface PatchReactImportsOptions {\n podsRoot: string;\n dryRun: boolean;\n}\n\nexport type PackageRevision = {\n path: string;\n version: string;\n config?: ExpoModuleConfig;\n duplicates?: PackageRevision[];\n};\n\nexport type SearchResults = {\n [moduleName: string]: PackageRevision;\n};\n\nexport interface ModuleAndroidProjectInfo {\n name: string;\n sourceDir: string;\n}\n\nexport interface ModuleAndroidPluginInfo {\n id: string;\n sourceDir: string;\n}\n\nexport interface ModuleDescriptorAndroid {\n packageName: string;\n projects: ModuleAndroidProjectInfo[];\n plugins?: ModuleAndroidPluginInfo[];\n modules: string[];\n}\n\nexport interface ModuleIosPodspecInfo {\n podName: string;\n podspecDir: string;\n}\nexport interface ModuleDescriptorIos {\n packageName: string;\n pods: ModuleIosPodspecInfo[];\n flags: Record<string, any> | undefined;\n swiftModuleNames: string[];\n modules: string[];\n appDelegateSubscribers: string[];\n reactDelegateHandlers: string[];\n debugOnly: boolean;\n}\n\nexport type ModuleDescriptor = ModuleDescriptorAndroid | ModuleDescriptorIos;\n\nexport interface AndroidGradlePluginDescriptor {\n /**\n * Gradle plugin ID\n */\n id: string;\n\n /**\n * Artifact group\n */\n group: string;\n\n /**\n * Relative path to the gradle plugin directory\n */\n sourceDir: string;\n}\n\n/**\n * Represents a raw config from `expo-module.json`.\n */\nexport interface RawExpoModuleConfig {\n /**\n * An array of supported platforms.\n */\n platforms?: SupportedPlatform[];\n\n /**\n * iOS-specific config.\n */\n ios?: {\n /**\n * Names of Swift native modules classes to put to the generated modules provider file.\n */\n modules?: string[];\n\n /**\n * Names of Swift native modules classes to put to the generated modules provider file.\n * @deprecated Deprecated in favor of `modules`. Might be removed in the future releases.\n */\n modulesClassNames?: string[];\n\n /**\n * Names of Swift classes that hooks into `ExpoAppDelegate` to receive AppDelegate life-cycle events.\n */\n appDelegateSubscribers?: string[];\n\n /**\n * Names of Swift classes that implement `ExpoReactDelegateHandler` to hook React instance creation.\n */\n reactDelegateHandlers?: string[];\n\n /**\n * Podspec relative path.\n * To have multiple podspecs, string array type is also supported.\n */\n podspecPath?: string | string[];\n\n /**\n * Swift product module name. If empty, the pod name is used for Swift imports.\n * To have multiple modules, string array is also supported.\n */\n swiftModuleName?: string | string[];\n\n /**\n * Whether this module will be added only to the debug configuration.\n * Defaults to false.\n */\n debugOnly?: boolean;\n };\n\n /**\n * Android-specific config.\n */\n android?: {\n /**\n * Full names (package + class name) of Kotlin native modules classes to put to the generated package provider file.\n */\n modules?: string[];\n\n /**\n * Full names (package + class name) of Kotlin native modules classes to put to the generated package provider file.\n * @deprecated Deprecated in favor of `modules`. Might be removed in the future releases.\n */\n modulesClassNames?: string[];\n\n /**\n * build.gradle relative path.\n * To have multiple build.gradle projects, string array type is also supported.\n */\n gradlePath?: string | string[];\n\n /**\n * Gradle plugins.\n */\n gradlePlugins?: AndroidGradlePluginDescriptor[];\n };\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "expo-modules-autolinking",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.3.0",
|
|
4
4
|
"description": "Scripts that autolink Expo modules.",
|
|
5
5
|
"main": "build/index.js",
|
|
6
6
|
"types": "build/index.d.ts",
|
|
@@ -48,5 +48,5 @@
|
|
|
48
48
|
"find-up": "^5.0.0",
|
|
49
49
|
"fs-extra": "^9.1.0"
|
|
50
50
|
},
|
|
51
|
-
"gitHead": "
|
|
51
|
+
"gitHead": "4ba50c428c8369bb6b3a51a860d4898ad4ccbe78"
|
|
52
52
|
}
|
|
@@ -16,6 +16,24 @@ class ExpoModuleGradleProject {
|
|
|
16
16
|
}
|
|
17
17
|
}
|
|
18
18
|
|
|
19
|
+
// Object representing a gradle plugin
|
|
20
|
+
class ExpoModuleGradlePlugin {
|
|
21
|
+
// ID of the gradle plugin
|
|
22
|
+
String id
|
|
23
|
+
|
|
24
|
+
// Artifact group
|
|
25
|
+
String group
|
|
26
|
+
|
|
27
|
+
// Path to the plugin folder
|
|
28
|
+
String sourceDir
|
|
29
|
+
|
|
30
|
+
ExpoModuleGradlePlugin(Object data) {
|
|
31
|
+
this.id = data.id
|
|
32
|
+
this.group = data.group
|
|
33
|
+
this.sourceDir = data.sourceDir
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
19
37
|
// Object representing a module.
|
|
20
38
|
class ExpoModule {
|
|
21
39
|
// Name of the JavaScript package
|
|
@@ -27,10 +45,14 @@ class ExpoModule {
|
|
|
27
45
|
// Gradle projects
|
|
28
46
|
ExpoModuleGradleProject[] projects
|
|
29
47
|
|
|
48
|
+
// Gradle plugins
|
|
49
|
+
ExpoModuleGradlePlugin[] plugins
|
|
50
|
+
|
|
30
51
|
ExpoModule(Object data) {
|
|
31
52
|
this.name = data.packageName
|
|
32
53
|
this.version = data.packageVersion
|
|
33
54
|
this.projects = data.projects.collect { new ExpoModuleGradleProject(it) }
|
|
55
|
+
this.plugins = data.plugins.collect { new ExpoModuleGradlePlugin(it) }
|
|
34
56
|
}
|
|
35
57
|
}
|
|
36
58
|
|
|
@@ -138,12 +160,16 @@ class ExpoAutolinkingManager {
|
|
|
138
160
|
|
|
139
161
|
class Colors {
|
|
140
162
|
static final String GREEN = "\u001B[32m"
|
|
163
|
+
static final String YELLOW = "\u001B[33m"
|
|
141
164
|
static final String RESET = "\u001B[0m"
|
|
142
165
|
}
|
|
166
|
+
class Emojis {
|
|
167
|
+
static final String INFORMATION = "\u2139\uFE0F"
|
|
168
|
+
}
|
|
143
169
|
|
|
144
|
-
// We can't cast a manager that is created in `settings.gradle` to the `ExpoAutolinkingManager`
|
|
145
|
-
// because if someone is using `buildSrc`, the `ExpoAutolinkingManager` class
|
|
146
|
-
// will be loaded by two different class loader - `settings.gradle` will use a diffrent loader.
|
|
170
|
+
// We can't cast a manager that is created in `settings.gradle` to the `ExpoAutolinkingManager`
|
|
171
|
+
// because if someone is using `buildSrc`, the `ExpoAutolinkingManager` class
|
|
172
|
+
// will be loaded by two different class loader - `settings.gradle` will use a diffrent loader.
|
|
147
173
|
// In the JVM, classes are equal only if were loaded by the same loader.
|
|
148
174
|
// There is nothing that we can do in that case, but to make our code safer, we check if the class name is the same.
|
|
149
175
|
def validateExpoAutolinkingManager(manager) {
|
|
@@ -166,6 +192,33 @@ if (rootProject instanceof ProjectDescriptor) {
|
|
|
166
192
|
include(":${moduleProject.name}")
|
|
167
193
|
project(":${moduleProject.name}").projectDir = new File(moduleProject.sourceDir)
|
|
168
194
|
}
|
|
195
|
+
for (modulePlugin in module.plugins) {
|
|
196
|
+
includeBuild(new File(modulePlugin.sourceDir))
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
// Add plugin classpath to the root project
|
|
201
|
+
gradle.beforeProject { project ->
|
|
202
|
+
if (project === project.rootProject) {
|
|
203
|
+
for (module in modules) {
|
|
204
|
+
for (modulePlugin in module.plugins) {
|
|
205
|
+
project.buildscript.dependencies.add('classpath', "${modulePlugin.group}:${modulePlugin.id}")
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
// Apply plugins for all app projects
|
|
212
|
+
gradle.afterProject { project ->
|
|
213
|
+
if (!project.plugins.hasPlugin('com.android.application')) {
|
|
214
|
+
return
|
|
215
|
+
}
|
|
216
|
+
for (module in modules) {
|
|
217
|
+
for (modulePlugin in module.plugins) {
|
|
218
|
+
println " ${Emojis.INFORMATION} ${Colors.YELLOW}Applying gradle plugin${Colors.RESET} '${Colors.GREEN}${modulePlugin.id}${Colors.RESET}' (${module.name}@${module.version})"
|
|
219
|
+
project.plugins.apply(modulePlugin.id)
|
|
220
|
+
}
|
|
221
|
+
}
|
|
169
222
|
}
|
|
170
223
|
|
|
171
224
|
// Save the manager in the shared context, so that we can later use it in `build.gradle`.
|
|
@@ -251,7 +304,7 @@ if (rootProject instanceof ProjectDescriptor) {
|
|
|
251
304
|
ExpoAutolinkingManager.generatePackageList(project, options)
|
|
252
305
|
}
|
|
253
306
|
|
|
254
|
-
ext.ensureDependeciesWereEvaluated = { Project project ->
|
|
307
|
+
ext.ensureDependeciesWereEvaluated = { Project project ->
|
|
255
308
|
if (!gradle.ext.has('expoAutolinkingManager')) {
|
|
256
309
|
return
|
|
257
310
|
}
|
|
@@ -269,7 +322,7 @@ if (rootProject instanceof ProjectDescriptor) {
|
|
|
269
322
|
if (moduleProject.name == project.name) {
|
|
270
323
|
continue
|
|
271
324
|
}
|
|
272
|
-
|
|
325
|
+
|
|
273
326
|
project.evaluationDependsOn(":${moduleProject.name}")
|
|
274
327
|
}
|
|
275
328
|
}
|
|
@@ -103,6 +103,11 @@ module Expo
|
|
|
103
103
|
@options.fetch(:providerName, Constants::MODULES_PROVIDER_FILE_NAME)
|
|
104
104
|
end
|
|
105
105
|
|
|
106
|
+
# Absolute path to `Pods/Target Support Files/<pods target name>/<modules provider file>` within the project path
|
|
107
|
+
public def modules_provider_path(target)
|
|
108
|
+
File.join(target.support_files_dir, modules_provider_name)
|
|
109
|
+
end
|
|
110
|
+
|
|
106
111
|
# For now there is no need to generate the modules provider for testing.
|
|
107
112
|
public def should_generate_modules_provider?
|
|
108
113
|
return !@options.fetch(:testsOnly, false)
|
|
@@ -126,20 +131,11 @@ module Expo
|
|
|
126
131
|
end
|
|
127
132
|
end
|
|
128
133
|
|
|
129
|
-
|
|
134
|
+
public def base_command_args
|
|
130
135
|
search_paths = @options.fetch(:searchPaths, @options.fetch(:modules_paths, nil))
|
|
131
136
|
ignore_paths = @options.fetch(:ignorePaths, nil)
|
|
132
137
|
exclude = @options.fetch(:exclude, [])
|
|
133
|
-
|
|
134
|
-
args = [
|
|
135
|
-
'node',
|
|
136
|
-
'--no-warnings',
|
|
137
|
-
'--eval',
|
|
138
|
-
'require(\'expo-modules-autolinking\')(process.argv.slice(1))',
|
|
139
|
-
command_name,
|
|
140
|
-
'--platform',
|
|
141
|
-
'ios'
|
|
142
|
-
]
|
|
138
|
+
args = []
|
|
143
139
|
|
|
144
140
|
if !search_paths.nil? && !search_paths.empty?
|
|
145
141
|
args.concat(search_paths)
|
|
@@ -156,11 +152,24 @@ module Expo
|
|
|
156
152
|
args
|
|
157
153
|
end
|
|
158
154
|
|
|
155
|
+
private def node_command_args(command_name)
|
|
156
|
+
eval_command_args = [
|
|
157
|
+
'node',
|
|
158
|
+
'--no-warnings',
|
|
159
|
+
'--eval',
|
|
160
|
+
'require(\'expo-modules-autolinking\')(process.argv.slice(1))',
|
|
161
|
+
command_name,
|
|
162
|
+
'--platform',
|
|
163
|
+
'ios'
|
|
164
|
+
]
|
|
165
|
+
return eval_command_args.concat(base_command_args())
|
|
166
|
+
end
|
|
167
|
+
|
|
159
168
|
private def resolve_command_args
|
|
160
169
|
node_command_args('resolve').concat(['--json'])
|
|
161
170
|
end
|
|
162
171
|
|
|
163
|
-
|
|
172
|
+
public def generate_package_list_command_args(target_path)
|
|
164
173
|
node_command_args('generate-package-list').concat([
|
|
165
174
|
'--target',
|
|
166
175
|
target_path
|
package/scripts/ios/constants.rb
CHANGED
|
@@ -3,5 +3,7 @@ module Expo
|
|
|
3
3
|
module Constants
|
|
4
4
|
GENERATED_GROUP_NAME = 'ExpoModulesProviders'
|
|
5
5
|
MODULES_PROVIDER_FILE_NAME = 'ExpoModulesProvider.swift'
|
|
6
|
+
CONFIGURE_PROJECT_BUILD_SCRIPT_NAME = '[Expo] Configure project'
|
|
7
|
+
CONFIGURE_PROJECT_SCRIPT_FILE_NAME = 'expo-configure-project.sh'
|
|
6
8
|
end
|
|
7
9
|
end
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
require 'fileutils'
|
|
2
|
+
require 'colored2'
|
|
1
3
|
|
|
2
4
|
module Expo
|
|
3
5
|
module ProjectIntegrator
|
|
@@ -32,15 +34,15 @@ module Expo
|
|
|
32
34
|
# The user target name (without `Pods-` prefix which is a part of `target.name`)
|
|
33
35
|
target_name = target.target_definition.name
|
|
34
36
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
native_target = project.native_targets.find { |native_target| native_target.name == target_name }
|
|
37
|
+
# PBXNativeTarget of the user target
|
|
38
|
+
native_target = project.native_targets.find { |native_target| native_target.name == target_name }
|
|
38
39
|
|
|
39
|
-
|
|
40
|
-
|
|
40
|
+
# Shorthand ref for the autolinking manager.
|
|
41
|
+
autolinking_manager = target.target_definition.autolinking_manager
|
|
41
42
|
|
|
42
|
-
|
|
43
|
-
|
|
43
|
+
UI.message '- Generating the provider for ' << target_name.green << ' target' do
|
|
44
|
+
# Get the absolute path to the modules provider
|
|
45
|
+
modules_provider_path = autolinking_manager.modules_provider_path(target)
|
|
44
46
|
|
|
45
47
|
# Run `expo-modules-autolinking` command to generate the file
|
|
46
48
|
autolinking_manager.generate_package_list(target_name, modules_provider_path)
|
|
@@ -62,6 +64,8 @@ module Expo
|
|
|
62
64
|
end
|
|
63
65
|
end
|
|
64
66
|
end
|
|
67
|
+
|
|
68
|
+
integrate_build_script(autolinking_manager, project, target, native_target)
|
|
65
69
|
end
|
|
66
70
|
|
|
67
71
|
# Remove the generated group if it has nothing left inside
|
|
@@ -128,5 +132,135 @@ module Expo
|
|
|
128
132
|
end
|
|
129
133
|
end
|
|
130
134
|
|
|
131
|
-
|
|
135
|
+
# Makes sure that the build script configuring the project is installed,
|
|
136
|
+
# is up-to-date and is placed before the "Compile Sources" phase.
|
|
137
|
+
def self.integrate_build_script(autolinking_manager, project, target, native_target)
|
|
138
|
+
build_phases = native_target.build_phases
|
|
139
|
+
modules_provider_path = autolinking_manager.modules_provider_path(target)
|
|
140
|
+
|
|
141
|
+
# Look for our own build script phase
|
|
142
|
+
xcode_build_script = native_target.shell_script_build_phases.find { |script|
|
|
143
|
+
script.name == Constants::CONFIGURE_PROJECT_BUILD_SCRIPT_NAME
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
if xcode_build_script.nil?
|
|
147
|
+
# Inform the user that we added a build script.
|
|
148
|
+
puts "[Expo] ".blue << "Installing the build script for target " << native_target.name.green
|
|
149
|
+
|
|
150
|
+
# Create a new build script in the target, it's added as the last phase
|
|
151
|
+
xcode_build_script = native_target.new_shell_script_build_phase(Constants::CONFIGURE_PROJECT_BUILD_SCRIPT_NAME)
|
|
152
|
+
end
|
|
153
|
+
|
|
154
|
+
# Make sure it is before the "Compile Sources" build phase
|
|
155
|
+
xcode_build_script_index = build_phases.find_index(xcode_build_script)
|
|
156
|
+
compile_sources_index = build_phases.find_index { |phase|
|
|
157
|
+
phase.is_a?(Xcodeproj::Project::PBXSourcesBuildPhase)
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
if xcode_build_script_index.nil?
|
|
161
|
+
# This is almost impossible to get here as the script was just created with `new_shell_script_build_phase`
|
|
162
|
+
# that puts the script at the end of the phases, but let's log it just in case.
|
|
163
|
+
puts "[Expo] ".blue << "Unable to find the configuring build script in the Xcode project".red
|
|
164
|
+
end
|
|
165
|
+
|
|
166
|
+
if compile_sources_index.nil?
|
|
167
|
+
# In this case the project will probably not compile but that's not our fault
|
|
168
|
+
# and it doesn't block us from updating our build script.
|
|
169
|
+
puts "[Expo] ".blue << "Unable to find the compilation build phase in the Xcode project".red
|
|
170
|
+
end
|
|
171
|
+
|
|
172
|
+
# Insert our script before the "Compile Sources" phase when necessary
|
|
173
|
+
unless compile_sources_index.nil? || xcode_build_script_index < compile_sources_index
|
|
174
|
+
build_phases.insert(
|
|
175
|
+
compile_sources_index,
|
|
176
|
+
build_phases.delete_at(xcode_build_script_index)
|
|
177
|
+
)
|
|
178
|
+
end
|
|
179
|
+
|
|
180
|
+
# Get path to the script that will be added to the target support files
|
|
181
|
+
support_script_path = File.join(target.support_files_dir, Constants::CONFIGURE_PROJECT_SCRIPT_FILE_NAME)
|
|
182
|
+
support_script_relative_path = Pathname.new(support_script_path).relative_path_from(project.project_dir)
|
|
183
|
+
|
|
184
|
+
# Write to the shell script so it's always in-sync with the autolinking configuration
|
|
185
|
+
IO.write(
|
|
186
|
+
support_script_path,
|
|
187
|
+
generate_support_script(autolinking_manager, modules_provider_path)
|
|
188
|
+
)
|
|
189
|
+
|
|
190
|
+
# Make the support script executable
|
|
191
|
+
FileUtils.chmod('+x', support_script_path)
|
|
192
|
+
|
|
193
|
+
# Force the build phase script to run on each build (including incremental builds)
|
|
194
|
+
xcode_build_script.always_out_of_date = '1'
|
|
195
|
+
|
|
196
|
+
# Make sure the build script in Xcode is up to date, but probably it's not going to change
|
|
197
|
+
# as it just runs the script generated in the target support files
|
|
198
|
+
xcode_build_script.shell_script = generate_xcode_build_script(support_script_relative_path)
|
|
199
|
+
end
|
|
200
|
+
|
|
201
|
+
# Generates the shell script of the build script phase.
|
|
202
|
+
# Try not to modify this since it involves changes in the pbxproj so
|
|
203
|
+
# it's better to modify the support script instead, if possible.
|
|
204
|
+
def self.generate_xcode_build_script(script_relative_path)
|
|
205
|
+
escaped_path = script_relative_path.to_s.gsub(/[^a-zA-Z0-9,\._\+@%\/\-]/) { |char| "\\#{char}" }
|
|
206
|
+
|
|
207
|
+
<<~XCODE_BUILD_SCRIPT
|
|
208
|
+
# This script configures Expo modules and generates the modules provider file.
|
|
209
|
+
bash -l -c "./#{escaped_path}"
|
|
210
|
+
XCODE_BUILD_SCRIPT
|
|
211
|
+
end
|
|
212
|
+
|
|
213
|
+
# Generates the support script that is executed by the build script phase.
|
|
214
|
+
def self.generate_support_script(autolinking_manager, modules_provider_path)
|
|
215
|
+
args = autolinking_manager.base_command_args.map { |arg| "\"#{arg}\"" }.join(' ')
|
|
216
|
+
|
|
217
|
+
<<~SUPPORT_SCRIPT
|
|
218
|
+
#!/usr/bin/env bash
|
|
219
|
+
# @generated by expo-modules-autolinking
|
|
220
|
+
|
|
221
|
+
set -eo pipefail
|
|
222
|
+
|
|
223
|
+
function with_node() {
|
|
224
|
+
# Start with a default
|
|
225
|
+
export NODE_BINARY=$(command -v node)
|
|
226
|
+
|
|
227
|
+
# Override the default with the global environment
|
|
228
|
+
ENV_PATH="$PODS_ROOT/../.xcode.env"
|
|
229
|
+
if [[ -f "$ENV_PATH" ]]; then
|
|
230
|
+
source "$ENV_PATH"
|
|
231
|
+
fi
|
|
232
|
+
|
|
233
|
+
# Override the global with the local environment
|
|
234
|
+
LOCAL_ENV_PATH="${ENV_PATH}.local"
|
|
235
|
+
if [[ -f "$LOCAL_ENV_PATH" ]]; then
|
|
236
|
+
source "$LOCAL_ENV_PATH"
|
|
237
|
+
fi
|
|
238
|
+
|
|
239
|
+
if [[ -n "$NODE_BINARY" && -x "$NODE_BINARY" ]]; then
|
|
240
|
+
echo "Node found at: ${NODE_BINARY}"
|
|
241
|
+
else
|
|
242
|
+
cat >&2 << NODE_NOT_FOUND
|
|
243
|
+
error: Could not find "node" executable while running an Xcode build script.
|
|
244
|
+
You need to specify the path to your Node.js executable by defining an environment variable named NODE_BINARY in your project's .xcode.env or .xcode.env.local file.
|
|
245
|
+
You can set this up quickly by running:
|
|
246
|
+
|
|
247
|
+
echo "export NODE_BINARY=\\$(command -v node)" >> .xcode.env
|
|
248
|
+
|
|
249
|
+
in the ios folder of your project.
|
|
250
|
+
NODE_NOT_FOUND
|
|
251
|
+
|
|
252
|
+
exit 1
|
|
253
|
+
fi
|
|
254
|
+
|
|
255
|
+
# Execute argument, if present
|
|
256
|
+
if [[ "$#" -gt 0 ]]; then
|
|
257
|
+
"$NODE_BINARY" "$@"
|
|
258
|
+
fi
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
with_node --no-warnings --eval "require(\'expo-modules-autolinking\')(process.argv.slice(1))" generate-package-list #{args} --target "#{modules_provider_path}"
|
|
262
|
+
SUPPORT_SCRIPT
|
|
263
|
+
end
|
|
264
|
+
|
|
265
|
+
end # module ProjectIntegrator
|
|
132
266
|
end # module Expo
|
package/src/ExpoModuleConfig.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { RawExpoModuleConfig, SupportedPlatform } from './types';
|
|
1
|
+
import { AndroidGradlePluginDescriptor, RawExpoModuleConfig, SupportedPlatform } from './types';
|
|
2
2
|
|
|
3
3
|
function arrayize<T>(value: T[] | T | undefined): T[] {
|
|
4
4
|
if (Array.isArray(value)) {
|
|
@@ -82,6 +82,13 @@ export class ExpoModuleConfig {
|
|
|
82
82
|
return arrayize(this.rawConfig.android?.gradlePath ?? []);
|
|
83
83
|
}
|
|
84
84
|
|
|
85
|
+
/**
|
|
86
|
+
* Returns gradle plugins descriptors defined by the module author.
|
|
87
|
+
*/
|
|
88
|
+
androidGradlePlugins(): AndroidGradlePluginDescriptor[] {
|
|
89
|
+
return arrayize(this.rawConfig.android?.gradlePlugins ?? []);
|
|
90
|
+
}
|
|
91
|
+
|
|
85
92
|
/**
|
|
86
93
|
* Returns serializable raw config.
|
|
87
94
|
*/
|
package/src/platforms/android.ts
CHANGED
|
@@ -58,9 +58,18 @@ export async function resolveModuleAsync(
|
|
|
58
58
|
};
|
|
59
59
|
});
|
|
60
60
|
|
|
61
|
+
const plugins = (revision.config?.androidGradlePlugins() ?? []).map(
|
|
62
|
+
({ id, group, sourceDir }) => ({
|
|
63
|
+
id,
|
|
64
|
+
group,
|
|
65
|
+
sourceDir: path.join(revision.path, sourceDir),
|
|
66
|
+
})
|
|
67
|
+
);
|
|
68
|
+
|
|
61
69
|
return {
|
|
62
70
|
packageName,
|
|
63
71
|
projects,
|
|
72
|
+
...(plugins.length > 0 ? { plugins } : {}),
|
|
64
73
|
modules: revision.config?.androidModules() ?? [],
|
|
65
74
|
};
|
|
66
75
|
}
|
package/src/types.ts
CHANGED
|
@@ -46,9 +46,15 @@ export interface ModuleAndroidProjectInfo {
|
|
|
46
46
|
sourceDir: string;
|
|
47
47
|
}
|
|
48
48
|
|
|
49
|
+
export interface ModuleAndroidPluginInfo {
|
|
50
|
+
id: string;
|
|
51
|
+
sourceDir: string;
|
|
52
|
+
}
|
|
53
|
+
|
|
49
54
|
export interface ModuleDescriptorAndroid {
|
|
50
55
|
packageName: string;
|
|
51
56
|
projects: ModuleAndroidProjectInfo[];
|
|
57
|
+
plugins?: ModuleAndroidPluginInfo[];
|
|
52
58
|
modules: string[];
|
|
53
59
|
}
|
|
54
60
|
|
|
@@ -69,6 +75,23 @@ export interface ModuleDescriptorIos {
|
|
|
69
75
|
|
|
70
76
|
export type ModuleDescriptor = ModuleDescriptorAndroid | ModuleDescriptorIos;
|
|
71
77
|
|
|
78
|
+
export interface AndroidGradlePluginDescriptor {
|
|
79
|
+
/**
|
|
80
|
+
* Gradle plugin ID
|
|
81
|
+
*/
|
|
82
|
+
id: string;
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* Artifact group
|
|
86
|
+
*/
|
|
87
|
+
group: string;
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* Relative path to the gradle plugin directory
|
|
91
|
+
*/
|
|
92
|
+
sourceDir: string;
|
|
93
|
+
}
|
|
94
|
+
|
|
72
95
|
/**
|
|
73
96
|
* Represents a raw config from `expo-module.json`.
|
|
74
97
|
*/
|
|
@@ -142,5 +165,10 @@ export interface RawExpoModuleConfig {
|
|
|
142
165
|
* To have multiple build.gradle projects, string array type is also supported.
|
|
143
166
|
*/
|
|
144
167
|
gradlePath?: string | string[];
|
|
168
|
+
|
|
169
|
+
/**
|
|
170
|
+
* Gradle plugins.
|
|
171
|
+
*/
|
|
172
|
+
gradlePlugins?: AndroidGradlePluginDescriptor[];
|
|
145
173
|
};
|
|
146
174
|
}
|