@callstack/react-native-brownfield 3.15.0 → 4.1.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.
Files changed (114) hide show
  1. package/gradle-plugin/brownfield/config/detekt/detekt.yml +1 -1
  2. package/gradle-plugin/brownfield/gradle.properties +1 -1
  3. package/gradle-plugin/brownfield/gradlew +0 -0
  4. package/gradle-plugin/brownfield/src/main/kotlin/com/callstack/react/brownfield/expo/utils/LocalMavenUtils.kt +2 -5
  5. package/gradle-plugin/brownfield/src/main/kotlin/com/callstack/react/brownfield/plugin/ProjectConfigurations.kt +3 -5
  6. package/gradle-plugin/brownfield/src/main/kotlin/com/callstack/react/brownfield/plugin/RNBrownfieldPlugin.kt +21 -26
  7. package/gradle-plugin/brownfield/src/main/kotlin/com/callstack/react/brownfield/plugin/RNSourceSets.kt +23 -28
  8. package/gradle-plugin/brownfield/src/main/kotlin/com/callstack/react/brownfield/processors/AssetTaskProcessor.kt +4 -16
  9. package/gradle-plugin/brownfield/src/main/kotlin/com/callstack/react/brownfield/processors/ExplodeTaskProvider.kt +6 -7
  10. package/gradle-plugin/brownfield/src/main/kotlin/com/callstack/react/brownfield/processors/JNILibsProcessor.kt +133 -110
  11. package/gradle-plugin/brownfield/src/main/kotlin/com/callstack/react/brownfield/processors/ManifestTaskProcessor.kt +25 -61
  12. package/gradle-plugin/brownfield/src/main/kotlin/com/callstack/react/brownfield/processors/MergeProcessor.kt +7 -29
  13. package/gradle-plugin/brownfield/src/main/kotlin/com/callstack/react/brownfield/processors/ProguardProcessor.kt +9 -46
  14. package/gradle-plugin/brownfield/src/main/kotlin/com/callstack/react/brownfield/processors/ResourceTaskProcessor.kt +4 -13
  15. package/gradle-plugin/brownfield/src/main/kotlin/com/callstack/react/brownfield/processors/VariantHelper.kt +52 -47
  16. package/gradle-plugin/brownfield/src/main/kotlin/com/callstack/react/brownfield/processors/VariantTaskProvider.kt +31 -63
  17. package/gradle-plugin/brownfield/src/main/kotlin/com/callstack/react/brownfield/shared/BundleTaskProvider.kt +72 -27
  18. package/gradle-plugin/brownfield/src/main/kotlin/com/callstack/react/brownfield/shared/Constants.kt +0 -1
  19. package/gradle-plugin/brownfield/src/main/kotlin/com/callstack/react/brownfield/shared/ExplodeAarTask.kt +2 -20
  20. package/gradle-plugin/brownfield/src/main/kotlin/com/callstack/react/brownfield/shared/Logging.kt +1 -1
  21. package/gradle-plugin/brownfield/src/main/kotlin/com/callstack/react/brownfield/shared/MergeClassesTask.kt +70 -0
  22. package/gradle-plugin/brownfield/src/main/kotlin/com/callstack/react/brownfield/shared/MergeLibraryManifestTask.kt +178 -0
  23. package/gradle-plugin/brownfield/src/main/kotlin/com/callstack/react/brownfield/utils/AndroidArchiveLibrary.kt +0 -4
  24. package/gradle-plugin/brownfield/src/main/kotlin/com/callstack/react/brownfield/utils/DirectoryManager.kt +0 -5
  25. package/gradle-plugin/brownfield/src/main/kotlin/com/callstack/react/brownfield/utils/Extension.kt +8 -9
  26. package/gradle-plugin/brownfield/src/main/kotlin/com/callstack/react/brownfield/utils/Utils.kt +2 -34
  27. package/lib/commonjs/expo-config-plugin/android/utils/constants.js +1 -1
  28. package/lib/commonjs/expo-config-plugin/android/utils/formatHelpers.js +2 -0
  29. package/lib/commonjs/expo-config-plugin/android/utils/formatHelpers.js.map +1 -0
  30. package/lib/commonjs/expo-config-plugin/android/utils/gradleHelpers.js +1 -1
  31. package/lib/commonjs/expo-config-plugin/android/utils/gradleHelpers.js.map +1 -1
  32. package/lib/commonjs/expo-config-plugin/android/withAndroidModuleFiles.js +1 -1
  33. package/lib/commonjs/expo-config-plugin/android/withAndroidModuleFiles.js.map +1 -1
  34. package/lib/commonjs/expo-config-plugin/android/withBrownfieldAndroid.js +1 -1
  35. package/lib/commonjs/expo-config-plugin/android/withBrownfieldAndroid.js.map +1 -1
  36. package/lib/commonjs/expo-config-plugin/expoUtils.js +1 -1
  37. package/lib/commonjs/expo-config-plugin/expoUtils.js.map +1 -1
  38. package/lib/commonjs/expo-config-plugin/ios/podfileHelpers.js +2 -8
  39. package/lib/commonjs/expo-config-plugin/ios/podfileHelpers.js.map +1 -1
  40. package/lib/commonjs/expo-config-plugin/ios/withBrownfieldIos.js +1 -1
  41. package/lib/commonjs/expo-config-plugin/ios/withBrownfieldIos.js.map +1 -1
  42. package/lib/commonjs/expo-config-plugin/ios/xcodeHelpers.js +2 -2
  43. package/lib/commonjs/expo-config-plugin/ios/xcodeHelpers.js.map +1 -1
  44. package/lib/commonjs/expo-config-plugin/template/android/build.gradle.kts +6 -0
  45. package/lib/commonjs/scripts/brownfield.js +0 -0
  46. package/lib/module/expo-config-plugin/android/utils/constants.js +1 -1
  47. package/lib/module/expo-config-plugin/android/utils/formatHelpers.js +2 -0
  48. package/lib/module/expo-config-plugin/android/utils/formatHelpers.js.map +1 -0
  49. package/lib/module/expo-config-plugin/android/utils/gradleHelpers.js +1 -1
  50. package/lib/module/expo-config-plugin/android/utils/gradleHelpers.js.map +1 -1
  51. package/lib/module/expo-config-plugin/android/withAndroidModuleFiles.js +1 -1
  52. package/lib/module/expo-config-plugin/android/withAndroidModuleFiles.js.map +1 -1
  53. package/lib/module/expo-config-plugin/android/withBrownfieldAndroid.js +1 -1
  54. package/lib/module/expo-config-plugin/android/withBrownfieldAndroid.js.map +1 -1
  55. package/lib/module/expo-config-plugin/expoUtils.js +1 -1
  56. package/lib/module/expo-config-plugin/expoUtils.js.map +1 -1
  57. package/lib/module/expo-config-plugin/ios/podfileHelpers.js +2 -8
  58. package/lib/module/expo-config-plugin/ios/podfileHelpers.js.map +1 -1
  59. package/lib/module/expo-config-plugin/ios/withBrownfieldIos.js +1 -1
  60. package/lib/module/expo-config-plugin/ios/withBrownfieldIos.js.map +1 -1
  61. package/lib/module/expo-config-plugin/ios/xcodeHelpers.js +2 -2
  62. package/lib/module/expo-config-plugin/ios/xcodeHelpers.js.map +1 -1
  63. package/lib/module/expo-config-plugin/template/android/build.gradle.kts +6 -0
  64. package/lib/typescript/commonjs/src/expo-config-plugin/android/utils/constants.d.ts +2 -2
  65. package/lib/typescript/commonjs/src/expo-config-plugin/android/utils/formatHelpers.d.ts +2 -0
  66. package/lib/typescript/commonjs/src/expo-config-plugin/android/utils/formatHelpers.d.ts.map +1 -0
  67. package/lib/typescript/commonjs/src/expo-config-plugin/android/utils/gradleHelpers.d.ts +7 -0
  68. package/lib/typescript/commonjs/src/expo-config-plugin/android/utils/gradleHelpers.d.ts.map +1 -1
  69. package/lib/typescript/commonjs/src/expo-config-plugin/android/withAndroidModuleFiles.d.ts +1 -5
  70. package/lib/typescript/commonjs/src/expo-config-plugin/android/withAndroidModuleFiles.d.ts.map +1 -1
  71. package/lib/typescript/commonjs/src/expo-config-plugin/android/withBrownfieldAndroid.d.ts.map +1 -1
  72. package/lib/typescript/commonjs/src/expo-config-plugin/expoUtils.d.ts +0 -1
  73. package/lib/typescript/commonjs/src/expo-config-plugin/expoUtils.d.ts.map +1 -1
  74. package/lib/typescript/commonjs/src/expo-config-plugin/ios/podfileHelpers.d.ts.map +1 -1
  75. package/lib/typescript/commonjs/src/expo-config-plugin/ios/withBrownfieldIos.d.ts.map +1 -1
  76. package/lib/typescript/commonjs/src/expo-config-plugin/ios/xcodeHelpers.d.ts +0 -16
  77. package/lib/typescript/commonjs/src/expo-config-plugin/ios/xcodeHelpers.d.ts.map +1 -1
  78. package/lib/typescript/commonjs/src/expo-config-plugin/types/android/BrownfieldPluginAndroidConfig.d.ts +5 -0
  79. package/lib/typescript/commonjs/src/expo-config-plugin/types/android/BrownfieldPluginAndroidConfig.d.ts.map +1 -1
  80. package/lib/typescript/module/src/expo-config-plugin/android/utils/constants.d.ts +2 -2
  81. package/lib/typescript/module/src/expo-config-plugin/android/utils/formatHelpers.d.ts +2 -0
  82. package/lib/typescript/module/src/expo-config-plugin/android/utils/formatHelpers.d.ts.map +1 -0
  83. package/lib/typescript/module/src/expo-config-plugin/android/utils/gradleHelpers.d.ts +7 -0
  84. package/lib/typescript/module/src/expo-config-plugin/android/utils/gradleHelpers.d.ts.map +1 -1
  85. package/lib/typescript/module/src/expo-config-plugin/android/withAndroidModuleFiles.d.ts +1 -5
  86. package/lib/typescript/module/src/expo-config-plugin/android/withAndroidModuleFiles.d.ts.map +1 -1
  87. package/lib/typescript/module/src/expo-config-plugin/android/withBrownfieldAndroid.d.ts.map +1 -1
  88. package/lib/typescript/module/src/expo-config-plugin/expoUtils.d.ts +0 -1
  89. package/lib/typescript/module/src/expo-config-plugin/expoUtils.d.ts.map +1 -1
  90. package/lib/typescript/module/src/expo-config-plugin/ios/podfileHelpers.d.ts.map +1 -1
  91. package/lib/typescript/module/src/expo-config-plugin/ios/withBrownfieldIos.d.ts.map +1 -1
  92. package/lib/typescript/module/src/expo-config-plugin/ios/xcodeHelpers.d.ts +0 -16
  93. package/lib/typescript/module/src/expo-config-plugin/ios/xcodeHelpers.d.ts.map +1 -1
  94. package/lib/typescript/module/src/expo-config-plugin/types/android/BrownfieldPluginAndroidConfig.d.ts +5 -0
  95. package/lib/typescript/module/src/expo-config-plugin/types/android/BrownfieldPluginAndroidConfig.d.ts.map +1 -1
  96. package/package.json +3 -3
  97. package/src/expo-config-plugin/android/utils/constants.ts +1 -1
  98. package/src/expo-config-plugin/android/utils/formatHelpers.ts +7 -0
  99. package/src/expo-config-plugin/android/utils/gradleHelpers.ts +41 -0
  100. package/src/expo-config-plugin/android/withAndroidModuleFiles.ts +23 -31
  101. package/src/expo-config-plugin/android/withBrownfieldAndroid.ts +16 -3
  102. package/src/expo-config-plugin/expoUtils.ts +1 -2
  103. package/src/expo-config-plugin/ios/podfileHelpers.ts +8 -52
  104. package/src/expo-config-plugin/ios/withBrownfieldIos.ts +1 -25
  105. package/src/expo-config-plugin/ios/xcodeHelpers.ts +0 -99
  106. package/src/expo-config-plugin/template/android/build.gradle.kts +6 -0
  107. package/src/expo-config-plugin/types/android/BrownfieldPluginAndroidConfig.ts +6 -0
  108. package/CHANGELOG.md +0 -287
  109. package/lib/commonjs/expo-config-plugin/template/android/ReactNativeHostManager.pre55.kt +0 -52
  110. package/lib/commonjs/expo-config-plugin/template/ios/patchExpoPre55.sh +0 -22
  111. package/lib/module/expo-config-plugin/template/android/ReactNativeHostManager.pre55.kt +0 -52
  112. package/lib/module/expo-config-plugin/template/ios/patchExpoPre55.sh +0 -22
  113. package/src/expo-config-plugin/template/android/ReactNativeHostManager.pre55.kt +0 -52
  114. package/src/expo-config-plugin/template/ios/patchExpoPre55.sh +0 -22
@@ -844,7 +844,7 @@ style:
844
844
  ignoredCharacters: []
845
845
  ThrowsCount:
846
846
  active: true
847
- max: 2
847
+ max: 3
848
848
  excludeGuardClauses: false
849
849
  TrailingWhitespace:
850
850
  active: false
@@ -1,6 +1,6 @@
1
1
  PROJECT_ID=com.callstack.react.brownfield
2
2
  ARTIFACT_ID=brownfield-gradle-plugin
3
- VERSION=2.0.0-alpha04
3
+ VERSION=2.0.0-alpha07
4
4
  GROUP=com.callstack.react
5
5
  IMPLEMENTATION_CLASS=com.callstack.react.brownfield.plugin.RNBrownfieldPlugin
6
6
 
File without changes
@@ -1,6 +1,6 @@
1
1
  package com.callstack.react.brownfield.expo.utils
2
2
 
3
- import com.android.build.gradle.LibraryExtension
3
+ import com.android.build.api.dsl.LibraryExtension
4
4
  import org.gradle.api.Project
5
5
  import java.io.File
6
6
 
@@ -68,10 +68,7 @@ object LocalMavenUtils {
68
68
  BrownfieldPublishingInfo(
69
69
  groupId = groupId,
70
70
  artifactId = artifactId,
71
- version = (
72
- targetProjectAndroidLibExt.defaultConfig.versionName
73
- ?: targetProject.version.toString()
74
- ),
71
+ version = targetProject.version.toString(),
75
72
  )
76
73
  )
77
74
  }
@@ -1,7 +1,7 @@
1
1
  package com.callstack.react.brownfield.plugin
2
2
 
3
+ import com.android.build.api.dsl.LibraryExtension
3
4
  import com.android.build.api.variant.LibraryAndroidComponentsExtension
4
- import com.android.build.gradle.LibraryExtension
5
5
  import com.callstack.react.brownfield.shared.Logging
6
6
  import com.callstack.react.brownfield.utils.capitalized
7
7
  import org.gradle.api.Project
@@ -70,7 +70,6 @@ class ProjectConfigurations(private val project: Project) {
70
70
  val configuration = project.configurations.create(configName)
71
71
 
72
72
  configuration.extendsFrom(project.configurations.getByName("implementation"))
73
- configuration.isVisible = false
74
73
  configuration.isTransitive = false
75
74
 
76
75
  val androidComponents = project.extensions.getByType(LibraryAndroidComponentsExtension::class.java)
@@ -96,9 +95,8 @@ class ProjectConfigurations(private val project: Project) {
96
95
  from: AttributeContainer,
97
96
  into: AttributeContainer,
98
97
  ) {
99
- val value: T? = from.getAttribute(key)
100
- if (value != null) {
101
- into.attribute(key, value)
98
+ from.getAttribute(key)?.let {
99
+ into.attribute(key, it)
102
100
  }
103
101
  }
104
102
 
@@ -1,7 +1,7 @@
1
1
  package com.callstack.react.brownfield.plugin
2
2
 
3
- import com.android.build.gradle.LibraryExtension
4
- import com.android.build.gradle.api.LibraryVariant
3
+ import com.android.build.api.variant.LibraryAndroidComponentsExtension
4
+ import com.android.build.api.variant.LibraryVariant
5
5
  import com.callstack.react.brownfield.artifacts.ArtifactsResolver
6
6
  import com.callstack.react.brownfield.expo.ExpoPublishingHelper
7
7
  import com.callstack.react.brownfield.expo.utils.ExpoGradleProjectProjection
@@ -11,6 +11,7 @@ import com.callstack.react.brownfield.processors.JNILibsProcessor
11
11
  import com.callstack.react.brownfield.processors.ManifestTaskProcessor
12
12
  import com.callstack.react.brownfield.processors.ProguardProcessor
13
13
  import com.callstack.react.brownfield.processors.ResourceTaskProcessor
14
+ import com.callstack.react.brownfield.processors.VariantHelper
14
15
  import com.callstack.react.brownfield.processors.VariantPackagesProperty
15
16
  import com.callstack.react.brownfield.processors.VariantTaskProvider
16
17
  import com.callstack.react.brownfield.shared.BaseProject
@@ -21,6 +22,7 @@ import com.callstack.react.brownfield.utils.AndroidArchiveLibrary
21
22
  import com.callstack.react.brownfield.utils.DirectoryManager
22
23
  import com.callstack.react.brownfield.utils.Extension
23
24
  import com.callstack.react.brownfield.utils.Utils
25
+ import com.callstack.react.brownfield.utils.capitalized
24
26
  import org.gradle.api.Plugin
25
27
  import org.gradle.api.Project
26
28
  import org.gradle.api.ProjectConfigurationException
@@ -65,11 +67,14 @@ class RNBrownfieldPlugin : Plugin<Project> {
65
67
 
66
68
  val variantTaskProvider = VariantTaskProvider(project)
67
69
 
68
- /**
69
- * Configure Tasks
70
- */
71
- project.extensions.getByType(LibraryExtension::class.java).libraryVariants.all { variant ->
70
+ val androidComponents = project.extensions.getByType(LibraryAndroidComponentsExtension::class.java)
71
+ androidComponents.onVariants { variant ->
72
72
  configureTasks(variant, artifacts, variantTaskProvider)
73
+
74
+ val aarLibraries = getAarLibraries(artifacts, variant.name)
75
+ ManifestTaskProcessor.process(variant, project, aarLibraries)
76
+ AssetTaskProcessor.process(variant, aarLibraries)
77
+ ResourceTaskProcessor.process(variant, aarLibraries)
73
78
  }
74
79
  }
75
80
 
@@ -124,48 +129,38 @@ class RNBrownfieldPlugin : Plugin<Project> {
124
129
  variantTaskProvider: VariantTaskProvider,
125
130
  ) {
126
131
  val variantName = variant.name
127
- val capitalizedVariantName = variantName.replaceFirstChar(Char::titlecase)
132
+ val capitalizedVariantName = variantName.capitalized()
128
133
 
129
134
  /** ======= EXPLODE AAR =========*/
130
135
  val explodeTask = ExplodeTaskProvider.getTask(variant, project, artifacts)
131
136
 
132
137
  /** ======= Pre<Variant>Build =========*/
133
138
  variantTaskProvider.preBuildTaskByVariant(
134
- variantName,
135
- variant.buildType.name,
136
- variant.buildType.isDebuggable,
139
+ variant,
137
140
  explodeTask,
138
141
  )
139
142
 
140
143
  val aarLibraries = getAarLibraries(artifacts, variantName)
141
144
 
145
+ /** ======= MERGE CLASSES =========*/
146
+ val mergeClassesTask = variantTaskProvider.mergeClasses(aarLibraries, explodeTask, variantName)
147
+ VariantHelper.getAsmTransformTask(project, capitalizedVariantName).configureEach {
148
+ it.dependsOn(mergeClassesTask)
149
+ }
150
+
142
151
  /**
143
152
  * Flat IDs to be put into the variant property, required for RClass Transformer
144
153
  */
145
154
  val packageIDs = aarLibraries.map { it.getPackageName() }
146
155
  VariantPackagesProperty.getVariantPackagesProperty().put(variantName, packageIDs)
147
156
 
148
- /** ======= MANIFEST MERGER =========*/
149
- ManifestTaskProcessor.process(variant, project, aarLibraries)
150
-
151
- /** ======= GENERATE RESOURCES =========*/
152
- ResourceTaskProcessor.process(variant, project, aarLibraries)
153
-
154
- /** ======= GENERATE ASSETS ========= */
155
- AssetTaskProcessor.process(variant, project, aarLibraries)
156
-
157
157
  /** ===== jniLibsProcessor ===== */
158
158
  val jniLibsProcessor = JNILibsProcessor(project)
159
- jniLibsProcessor.processJniLibs(aarLibraries, variantName)
159
+ jniLibsProcessor.processJniLibs(aarLibraries, variant)
160
160
 
161
161
  /** ===== proguardProcessor ===== */
162
162
  val proguardProcessor = ProguardProcessor(project)
163
163
  val proguardRules = aarLibraries.map { it.getProguardRules() }
164
- proguardProcessor.processConsumerFiles(proguardRules, capitalizedVariantName)
165
- proguardProcessor.processGeneratedFiles(proguardRules, capitalizedVariantName)
166
-
167
- /** ===== processDataBinding ===== */
168
- val bundleTask = variantTaskProvider.bundleTaskProvider(project, variantName)
169
- variantTaskProvider.processDataBinding(bundleTask, aarLibraries, variantName)
164
+ proguardProcessor.processFiles(proguardRules, variantName.capitalized(), explodeTask)
170
165
  }
171
166
  }
@@ -1,8 +1,9 @@
1
1
  package com.callstack.react.brownfield.plugin
2
2
 
3
+ import com.android.build.api.dsl.LibraryExtension
3
4
  import com.android.build.api.variant.LibraryAndroidComponentsExtension
4
- import com.android.build.gradle.LibraryExtension
5
5
  import com.callstack.react.brownfield.exceptions.NameSpaceNotFound
6
+ import com.callstack.react.brownfield.processors.VariantHelper
6
7
  import com.callstack.react.brownfield.utils.Extension
7
8
  import com.callstack.react.brownfield.utils.Utils
8
9
  import com.callstack.react.brownfield.utils.capitalized
@@ -42,14 +43,14 @@ object RNSourceSets {
42
43
  // Move the non-variant-specific configuration out of the loop
43
44
  androidExtension.sourceSets.named("main") { sourceSet ->
44
45
  // This path is not variant-specific, so it's added once here.
45
- sourceSet.java.srcDir("${getModuleBuildDir()}/generated/autolinking/src/main/java")
46
+ sourceSet.java.directories.add("${getModuleBuildDir()}/generated/autolinking/src/main/java")
46
47
  }
47
48
 
48
- // 2. Use the onVariants block to configure each variant
49
+ // 2. Use the onVariants block to wire RN bundle outputs via the Variant Sources API
49
50
  componentsExtension.onVariants { variant ->
50
51
  val variantName = variant.name
51
52
  val bundledAssetsVariantName =
52
- Utils.getBundledAssetsVariantName(
53
+ VariantHelper.getBundledAssetsVariantName(
53
54
  variantName = variantName,
54
55
  buildTypeName = variant.buildType,
55
56
  isDebuggable = variant.debuggable,
@@ -57,30 +58,24 @@ object RNSourceSets {
57
58
  val capitalizedBundledAssetsVariantName = bundledAssetsVariantName.capitalized()
58
59
  val appProject = getAppProject()
59
60
 
60
- // 3. Lazily configure the 'variant-specific' source set using .named()
61
- androidExtension.sourceSets.named(variantName) { sourceSet ->
62
- val bundlePathSegments =
63
- listOf(
64
- // outputs for RN <= 0.81
65
- "createBundle${capitalizedBundledAssetsVariantName}JsAndAssets",
66
- // outputs for RN >= 0.82
67
- "react/$bundledAssetsVariantName",
68
- )
69
- val updateResourcesPathSegment = Utils.getExpoUpdatesResourcesTaskName(variant.name)
70
-
71
- val appBuildDir = getAppBuildDir()
72
- sourceSet.assets.srcDirs(bundlePathSegments.map { "$appBuildDir/generated/assets/$it" })
73
- sourceSet.res.srcDirs(bundlePathSegments.map { "$appBuildDir/generated/res/$it" })
74
- sourceSet.jniLibs.srcDirs("libs${variantName.capitalized()}")
75
- if (Utils.hasExpoUpdates(appProject, variant.name)) {
76
- val updateResourcesTask = appProject.tasks.named(updateResourcesPathSegment)
77
- sourceSet.assets.srcDir(
78
- project.files("$appBuildDir/generated/assets/$updateResourcesPathSegment").builtBy(updateResourcesTask),
79
- )
80
- sourceSet.res.srcDir(
81
- project.files("$appBuildDir/generated/res/$updateResourcesPathSegment").builtBy(updateResourcesTask),
82
- )
83
- }
61
+ val bundlePathSegments =
62
+ listOf(
63
+ // outputs for RN <= 0.81
64
+ "createBundle${capitalizedBundledAssetsVariantName}JsAndAssets",
65
+ // outputs for RN >= 0.82
66
+ "react/$bundledAssetsVariantName",
67
+ )
68
+
69
+ val appBuildDir = getAppBuildDir()
70
+ bundlePathSegments.forEach { segment ->
71
+ variant.sources.assets?.addStaticSourceDirectory("$appBuildDir/generated/assets/$segment")
72
+ variant.sources.res?.addStaticSourceDirectory("$appBuildDir/generated/res/$segment")
73
+ }
74
+
75
+ if (Utils.hasExpoUpdates(appProject, variantName)) {
76
+ val updateResourcesPathSegment = VariantHelper.getExpoUpdatesResourcesTaskName(variant.name)
77
+ variant.sources.assets?.addStaticSourceDirectory("$appBuildDir/generated/assets/$updateResourcesPathSegment")
78
+ variant.sources.res?.addStaticSourceDirectory("$appBuildDir/generated/res/$updateResourcesPathSegment")
84
79
  }
85
80
  }
86
81
  }
@@ -1,29 +1,17 @@
1
1
  package com.callstack.react.brownfield.processors
2
2
 
3
- import com.android.build.gradle.LibraryExtension
4
- import com.android.build.gradle.api.LibraryVariant
3
+ import com.android.build.api.variant.LibraryVariant
5
4
  import com.callstack.react.brownfield.utils.AndroidArchiveLibrary
6
- import org.gradle.api.Project
7
5
 
8
6
  object AssetTaskProcessor {
9
7
  fun process(
10
8
  variant: LibraryVariant,
11
- project: Project,
12
9
  aarLibraries: List<AndroidArchiveLibrary>,
13
10
  ) {
14
- val assetsTask = variant.mergeAssetsProvider.get()
11
+ val assetDirectories = aarLibraries.map { it.getAssetsDir() }.filter { it.exists() }
15
12
 
16
- val androidExtension = project.extensions.getByName("android") as LibraryExtension
17
- assetsTask.doFirst {
18
- val filteredSourceSets =
19
- androidExtension.sourceSets.filter { it.name == variant.name }
20
-
21
- filteredSourceSets.forEach { sourceSet ->
22
- val filteredAarLibs = aarLibraries.filter { it.getAssetsDir().exists() }
23
- if (!filteredAarLibs.isEmpty()) {
24
- sourceSet.assets.srcDirs(filteredAarLibs.map { it.getAssetsDir() })
25
- }
26
- }
13
+ assetDirectories.forEach { assetDirectory ->
14
+ variant.sources.assets?.addStaticSourceDirectory(assetDirectory.path)
27
15
  }
28
16
  }
29
17
  }
@@ -1,9 +1,10 @@
1
1
  package com.callstack.react.brownfield.processors
2
2
 
3
- import com.android.build.gradle.api.LibraryVariant
3
+ import com.android.build.api.variant.LibraryVariant
4
4
  import com.callstack.react.brownfield.shared.BundleTaskProvider
5
5
  import com.callstack.react.brownfield.shared.ExplodeAarTask
6
6
  import com.callstack.react.brownfield.shared.UnresolvedArtifactInfo
7
+ import com.callstack.react.brownfield.utils.Extension
7
8
  import com.callstack.react.brownfield.utils.capitalized
8
9
  import org.gradle.api.Project
9
10
  import org.gradle.api.Task
@@ -20,25 +21,23 @@ object ExplodeTaskProvider {
20
21
  val variantTaskProvider = VariantTaskProvider(project)
21
22
  val bundleProvider = BundleTaskProvider(variantTaskProvider)
22
23
  val capitalizedVariantName = variant.name.capitalized()
24
+ val projectExt = project.extensions.getByType(Extension::class.java)
23
25
 
24
26
  return project.tasks.register(
25
27
  "explode${capitalizedVariantName}Aar",
26
28
  ExplodeAarTask::class.java,
27
29
  ) { task ->
28
30
  task.variantName.set(variant.name)
29
- task.minifyEnabled.set(variant.buildType.isMinifyEnabled)
30
31
 
31
32
  val finalArtifacts = mutableListOf<UnresolvedArtifactInfo>()
32
33
  artifacts.forEach { art ->
33
34
  var artifactPath = art.file
34
35
  if (art.isExpoPublishDependency != true) {
35
- val defaultTaskName = "bundle${capitalizedVariantName}Aar"
36
36
  val dependencyProject = project.project(":${art.moduleName}")
37
- val bundleTaskProvider = bundleProvider.getBundleTask(dependencyProject, variant)
38
- val taskName = bundleTaskProvider?.name ?: defaultTaskName
39
-
37
+ val bundleTaskProvider = bundleProvider.getBundleTask(dependencyProject, variant, projectExt.missingDimensionStrategies)
38
+ val taskName = bundleTaskProvider.name
40
39
  dependencyProject.tasks.findByName(taskName)?.let { task.dependsOn(it) }
41
- artifactPath = createArtifactFile(bundleTaskProvider?.get() as Task).absolutePath
40
+ artifactPath = createArtifactFile(bundleTaskProvider.get()).absolutePath
42
41
  }
43
42
 
44
43
  finalArtifacts.add(
@@ -1,144 +1,134 @@
1
1
  package com.callstack.react.brownfield.processors
2
2
 
3
- import com.android.build.gradle.LibraryExtension
4
- import com.callstack.react.brownfield.exceptions.TaskNotFound
3
+ import com.android.build.api.variant.LibraryVariant
5
4
  import com.callstack.react.brownfield.shared.Logging
6
5
  import com.callstack.react.brownfield.utils.AndroidArchiveLibrary
7
6
  import com.callstack.react.brownfield.utils.Extension
8
7
  import com.callstack.react.brownfield.utils.capitalized
8
+ import org.gradle.api.DefaultTask
9
9
  import org.gradle.api.Project
10
- import org.gradle.api.tasks.Copy
11
- import org.gradle.api.tasks.TaskProvider
10
+ import org.gradle.api.file.ConfigurableFileCollection
11
+ import org.gradle.api.file.DirectoryProperty
12
+ import org.gradle.api.provider.Property
13
+ import org.gradle.api.tasks.CacheableTask
14
+ import org.gradle.api.tasks.Input
15
+ import org.gradle.api.tasks.InputDirectory
16
+ import org.gradle.api.tasks.InputFiles
17
+ import org.gradle.api.tasks.Optional
18
+ import org.gradle.api.tasks.OutputDirectory
19
+ import org.gradle.api.tasks.PathSensitive
20
+ import org.gradle.api.tasks.PathSensitivity
21
+ import org.gradle.api.tasks.TaskAction
12
22
  import java.io.File
13
-
14
- class JNILibsProcessor(val project: Project) {
15
- fun processJniLibs(
16
- aarLibraries: Collection<AndroidArchiveLibrary>,
17
- variantName: String,
18
- ) {
19
- val capitalizedVariantName = variantName.capitalized()
20
- val taskName = "merge${capitalizedVariantName}JniLibFolders"
21
- val mergeJniLibsTask = project.tasks.named(taskName)
22
-
23
- if (!mergeJniLibsTask.isPresent) {
24
- throw TaskNotFound("Task $taskName not found")
25
- }
26
-
27
- val androidExtension = project.extensions.getByName("android") as LibraryExtension
28
- val copyTask = copySoLibsTask(variantName)
29
-
30
- mergeJniLibsTask.configure {
31
- it.dependsOn(copyTask)
32
-
33
- it.doFirst {
34
- val projectExt = project.extensions.getByType(Extension::class.java)
35
- val existingJNILibs =
36
- listOf("arm64-v8a", "armeabi-v7a", "x86_64", "x86")
37
- .associateWith { mutableListOf<String>() }
38
- .toMutableMap()
39
- for (archiveLibrary in aarLibraries) {
40
- val jniDir = archiveLibrary.getJniDir()
41
- processNestedLibs(jniDir.listFiles(), existingJNILibs)
42
- if (!projectExt.useStrippedSoFiles) {
43
- if (jniDir.exists()) {
44
- val filteredSourceSets =
45
- androidExtension.sourceSets.filter { sourceSet -> sourceSet.name == variantName }
46
- filteredSourceSets.forEach { sourceSet ->
47
- sourceSet.jniLibs.srcDir(
48
- jniDir,
49
- )
50
- }
51
- }
52
- }
53
- }
54
- if (projectExt.useStrippedSoFiles) {
55
- copyStrippedSoLibs(variantName, existingJNILibs)
23
+ import kotlin.collections.component1
24
+ import kotlin.collections.component2
25
+
26
+ /**
27
+ * Below contains a list of dynamic libs which we should not embed
28
+ * with the AAR as they are provided by the Gradle when AAR is
29
+ * consumed by the host App.
30
+ */
31
+ val IGNORE_EMBEDDED_LIBS =
32
+ listOf(
33
+ "libc++_shared.so", "libfbjni.so", "libhermestooling.so",
34
+ "libhermesvm.so", "libimagepipeline.so", "libjsi.so",
35
+ "libnative-filters.so", "libnative-imagetranscoder.so",
36
+ "libreactnative.so",
37
+ )
38
+
39
+ @CacheableTask
40
+ abstract class ProcessAndCopyJniLibsTask : DefaultTask() {
41
+ @get:InputFiles
42
+ @get:PathSensitive(PathSensitivity.RELATIVE)
43
+ abstract val aarJniDirs: ConfigurableFileCollection
44
+
45
+ @get:InputDirectory
46
+ @get:Optional
47
+ @get:PathSensitive(PathSensitivity.RELATIVE)
48
+ abstract val strippedLibsDir: DirectoryProperty
49
+
50
+ @get:Input
51
+ abstract val useStrippedSoFiles: Property<Boolean>
52
+
53
+ @get:OutputDirectory
54
+ abstract val outputDirectory: DirectoryProperty
55
+
56
+ @TaskAction
57
+ fun execute() {
58
+ val outDir = outputDirectory.get().asFile
59
+ // Clear out old data to ensure clean, reproducible builds
60
+ outDir.deleteRecursively()
61
+ outDir.mkdirs()
62
+
63
+ val existingJNILibs =
64
+ listOf("arm64-v8a", "armeabi-v7a", "x86_64", "x86")
65
+ .associateWith { mutableListOf<String>() }
66
+ .toMutableMap()
67
+
68
+ // 1. Scan and process duplicate libs from AAR paths
69
+ aarJniDirs.forEach { jniDir ->
70
+ if (jniDir.exists()) {
71
+ processNestedLibs(jniDir.listFiles(), existingJNILibs)
72
+
73
+ // If not using stripped files, copy the unstripped ones directly to our output
74
+ if (!useStrippedSoFiles.get()) {
75
+ jniDir.copyRecursively(outDir, overwrite = true)
56
76
  }
57
77
  }
58
78
  }
59
- }
60
-
61
- private fun getStrippedLibsPath(variantName: String): Pair<File, File> {
62
- val projectExt = project.extensions.getByType(Extension::class.java)
63
- val appProject = project.rootProject.project(projectExt.appProjectName)
64
- val appBuildDir = appProject.layout.buildDirectory.get()
65
-
66
- val capitalizedVariant = variantName.capitalized()
67
-
68
- val fromDir =
69
- appBuildDir
70
- .dir("intermediates/stripped_native_libs/$variantName/strip${capitalizedVariant}DebugSymbols/out/lib")
71
- .asFile
72
-
73
- val intoDir = project.rootProject.file("${project.name}/libs$capitalizedVariant")
74
-
75
- return Pair(fromDir, intoDir)
76
- }
77
-
78
- private fun copySoLibsTask(variantName: String): TaskProvider<Copy> {
79
- val capitalizedVariant = variantName.capitalized()
80
- val projectExt = project.extensions.getByType(Extension::class.java)
81
- val appProject = project.rootProject.project(projectExt.appProjectName)
82
-
83
- val stripTask = ":${appProject.name}:strip${capitalizedVariant}DebugSymbols"
84
- val codegenTask = ":${project.name}:generateCodegenSchemaFromJavaScript"
85
79
 
86
- val (fromDir, intoDir) = getStrippedLibsPath(variantName)
87
-
88
- return project.tasks.register("copy${capitalizedVariant}LibSources", Copy::class.java) {
89
- it.dependsOn(stripTask, codegenTask)
90
- it.from(fromDir)
91
- it.into(intoDir)
92
-
93
- it.include("**/libappmodules.so", "**/libreact_codegen_*.so")
94
- projectExt.dynamicLibs.forEach { lib -> it.include("**/$lib") }
80
+ // 2. If using stripped files, copy targeted files from the stripped directory
81
+ if (useStrippedSoFiles.get() && strippedLibsDir.isPresent) {
82
+ copyStrippedSoLibs(outDir, existingJNILibs)
95
83
  }
96
84
  }
97
85
 
98
86
  private fun copyStrippedSoLibs(
99
- variantName: String,
87
+ outDir: File,
100
88
  existingJNILibs: MutableMap<String, MutableList<String>>,
101
89
  ) {
102
- val (fromDir, intoDir) = getStrippedLibsPath(variantName)
90
+ val fromDir = strippedLibsDir.get().asFile
91
+ if (!fromDir.exists()) return
103
92
 
104
- existingJNILibs.forEach { (arch, libNames) ->
105
- copyLibsForArchitecture(fromDir, intoDir, arch, libNames)
93
+ existingJNILibs.keys.forEach { arch ->
94
+ copyArchStrippedSoLibs(fromDir, outDir, arch)
106
95
  }
107
96
  }
108
97
 
109
- private fun copyLibsForArchitecture(
98
+ private fun copyArchStrippedSoLibs(
110
99
  fromDir: File,
111
- intoDir: File,
100
+ outDir: File,
112
101
  arch: String,
113
- libNames: List<String>,
114
102
  ) {
115
103
  val sourceArchDir = File(fromDir, arch)
116
104
  if (!sourceArchDir.exists()) return
117
105
 
118
- val destArchDir = File(intoDir, arch).apply { mkdirs() }
119
-
120
- libNames.forEach { libName ->
121
- copyLibFile(sourceArchDir, destArchDir, libName)
106
+ val destArchDir = File(outDir, arch).apply { mkdirs() }
107
+ sourceArchDir.listFiles()?.forEach { file ->
108
+ copyIfAllowed(file, destArchDir)
122
109
  }
123
110
  }
124
111
 
125
- private fun copyLibFile(
126
- sourceArchDir: File,
112
+ private fun copyIfAllowed(
113
+ file: File,
127
114
  destArchDir: File,
128
- libName: String,
129
115
  ) {
130
- val sourceFile = File(sourceArchDir, libName)
131
- val destFile = File(destArchDir, libName)
132
-
133
- if (sourceFile.exists()) {
134
- try {
135
- sourceFile.copyTo(destFile, overwrite = true)
136
- } catch (e: java.io.IOException) {
137
- Logging.log("Failed to copy $libName: ${e.message}")
138
- }
116
+ val name = file.name
117
+ if (!matchesAllowedLib(name)) return
118
+
119
+ try {
120
+ file.copyTo(File(destArchDir, name), overwrite = true)
121
+ } catch (e: java.io.IOException) {
122
+ Logging.error("Failed to copy $name: ${e.message}", e.cause)
139
123
  }
140
124
  }
141
125
 
126
+ private fun matchesAllowedLib(name: String): Boolean {
127
+ val isCodegenLib = name.startsWith("libreact_codegen_") && name.endsWith(".so")
128
+ val isIgnoredLib = IGNORE_EMBEDDED_LIBS.any { lib -> name == lib || name.contains(lib) }
129
+ return name == "libappmodules.so" || isCodegenLib || !isIgnoredLib
130
+ }
131
+
142
132
  private fun processNestedLibs(
143
133
  files: Array<File>?,
144
134
  existingJNILibs: MutableMap<String, MutableList<String>>,
@@ -149,17 +139,50 @@ class JNILibsProcessor(val project: Project) {
149
139
 
150
140
  libFiles.forEach { file ->
151
141
  if (file.name in libList) {
152
- deleteFile(file)
142
+ file.delete()
153
143
  } else {
154
144
  libList.add(file.name)
155
145
  }
156
146
  }
157
147
  }
158
148
  }
149
+ }
159
150
 
160
- private fun deleteFile(file: File) {
161
- if (!file.delete()) {
162
- Logging.log("Failed to delete: ${file.name}")
163
- }
151
+ class JNILibsProcessor(val project: Project) {
152
+ fun processJniLibs(
153
+ aarLibraries: Collection<AndroidArchiveLibrary>,
154
+ variant: LibraryVariant,
155
+ ) {
156
+ val variantName = variant.name
157
+ val capitalizedVariantName = variantName.capitalized()
158
+ val projectExt = project.extensions.getByType(Extension::class.java)
159
+ val appProject = project.rootProject.project(projectExt.appProjectName)
160
+
161
+ val processJniTask =
162
+ project.tasks.register("processCustomJniLibsFor$capitalizedVariantName", ProcessAndCopyJniLibsTask::class.java) {
163
+ it.useStrippedSoFiles.set(projectExt.useStrippedSoFiles)
164
+
165
+ val jniDirs =
166
+ aarLibraries.map { aarLib ->
167
+ aarLib.getJniDir()
168
+ }
169
+
170
+ it.aarJniDirs.setFrom(jniDirs)
171
+
172
+ val fromDirProvider =
173
+ appProject.layout.buildDirectory.dir(
174
+ "intermediates/stripped_native_libs/$variantName/strip${capitalizedVariantName}DebugSymbols/out/lib",
175
+ )
176
+ it.strippedLibsDir.set(fromDirProvider)
177
+
178
+ val stripTaskPath = ":${appProject.name}:strip${capitalizedVariantName}DebugSymbols"
179
+ val codegenTaskPath = ":${project.name}:generateCodegenSchemaFromJavaScript"
180
+ it.dependsOn(stripTaskPath, codegenTaskPath)
181
+ }
182
+
183
+ variant.sources.jniLibs?.addGeneratedSourceDirectory(
184
+ taskProvider = processJniTask,
185
+ wiredWith = { it.outputDirectory },
186
+ )
164
187
  }
165
188
  }