@callstack/react-native-brownfield 4.0.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 (74) 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 -35
  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 -108
  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/template/android/build.gradle.kts +6 -0
  37. package/lib/commonjs/scripts/brownfield.js +0 -0
  38. package/lib/module/expo-config-plugin/android/utils/constants.js +1 -1
  39. package/lib/module/expo-config-plugin/android/utils/formatHelpers.js +2 -0
  40. package/lib/module/expo-config-plugin/android/utils/formatHelpers.js.map +1 -0
  41. package/lib/module/expo-config-plugin/android/utils/gradleHelpers.js +1 -1
  42. package/lib/module/expo-config-plugin/android/utils/gradleHelpers.js.map +1 -1
  43. package/lib/module/expo-config-plugin/android/withAndroidModuleFiles.js +1 -1
  44. package/lib/module/expo-config-plugin/android/withAndroidModuleFiles.js.map +1 -1
  45. package/lib/module/expo-config-plugin/android/withBrownfieldAndroid.js +1 -1
  46. package/lib/module/expo-config-plugin/android/withBrownfieldAndroid.js.map +1 -1
  47. package/lib/module/expo-config-plugin/template/android/build.gradle.kts +6 -0
  48. package/lib/typescript/commonjs/src/expo-config-plugin/android/utils/constants.d.ts +2 -2
  49. package/lib/typescript/commonjs/src/expo-config-plugin/android/utils/formatHelpers.d.ts +2 -0
  50. package/lib/typescript/commonjs/src/expo-config-plugin/android/utils/formatHelpers.d.ts.map +1 -0
  51. package/lib/typescript/commonjs/src/expo-config-plugin/android/utils/gradleHelpers.d.ts +7 -0
  52. package/lib/typescript/commonjs/src/expo-config-plugin/android/utils/gradleHelpers.d.ts.map +1 -1
  53. package/lib/typescript/commonjs/src/expo-config-plugin/android/withAndroidModuleFiles.d.ts.map +1 -1
  54. package/lib/typescript/commonjs/src/expo-config-plugin/android/withBrownfieldAndroid.d.ts.map +1 -1
  55. package/lib/typescript/commonjs/src/expo-config-plugin/types/android/BrownfieldPluginAndroidConfig.d.ts +5 -0
  56. package/lib/typescript/commonjs/src/expo-config-plugin/types/android/BrownfieldPluginAndroidConfig.d.ts.map +1 -1
  57. package/lib/typescript/module/src/expo-config-plugin/android/utils/constants.d.ts +2 -2
  58. package/lib/typescript/module/src/expo-config-plugin/android/utils/formatHelpers.d.ts +2 -0
  59. package/lib/typescript/module/src/expo-config-plugin/android/utils/formatHelpers.d.ts.map +1 -0
  60. package/lib/typescript/module/src/expo-config-plugin/android/utils/gradleHelpers.d.ts +7 -0
  61. package/lib/typescript/module/src/expo-config-plugin/android/utils/gradleHelpers.d.ts.map +1 -1
  62. package/lib/typescript/module/src/expo-config-plugin/android/withAndroidModuleFiles.d.ts.map +1 -1
  63. package/lib/typescript/module/src/expo-config-plugin/android/withBrownfieldAndroid.d.ts.map +1 -1
  64. package/lib/typescript/module/src/expo-config-plugin/types/android/BrownfieldPluginAndroidConfig.d.ts +5 -0
  65. package/lib/typescript/module/src/expo-config-plugin/types/android/BrownfieldPluginAndroidConfig.d.ts.map +1 -1
  66. package/package.json +3 -3
  67. package/src/expo-config-plugin/android/utils/constants.ts +1 -1
  68. package/src/expo-config-plugin/android/utils/formatHelpers.ts +7 -0
  69. package/src/expo-config-plugin/android/utils/gradleHelpers.ts +41 -0
  70. package/src/expo-config-plugin/android/withAndroidModuleFiles.ts +20 -0
  71. package/src/expo-config-plugin/android/withBrownfieldAndroid.ts +16 -3
  72. package/src/expo-config-plugin/template/android/build.gradle.kts +6 -0
  73. package/src/expo-config-plugin/types/android/BrownfieldPluginAndroidConfig.ts +6 -0
  74. package/CHANGELOG.md +0 -300
@@ -1,20 +1,10 @@
1
1
  package com.callstack.react.brownfield.processors
2
2
 
3
- import com.android.build.gradle.api.LibraryVariant
4
- import com.android.manifmerger.ManifestMerger2
5
- import com.android.manifmerger.ManifestProvider
6
- import com.android.manifmerger.MergingReport
7
- import com.android.utils.ILogger
8
- import com.callstack.react.brownfield.shared.GradleILogger
3
+ import com.android.build.api.artifact.SingleArtifact
4
+ import com.android.build.api.variant.LibraryVariant
5
+ import com.callstack.react.brownfield.shared.MergeLibraryManifestTask
9
6
  import com.callstack.react.brownfield.utils.AndroidArchiveLibrary
10
- import com.callstack.react.brownfield.utils.capitalized
11
- import org.apache.tools.ant.BuildException
12
7
  import org.gradle.api.Project
13
- import org.gradle.api.logging.Logger
14
- import java.io.BufferedWriter
15
- import java.io.File
16
- import java.io.FileOutputStream
17
- import java.io.OutputStreamWriter
18
8
 
19
9
  object ManifestTaskProcessor {
20
10
  fun process(
@@ -22,53 +12,27 @@ object ManifestTaskProcessor {
22
12
  project: Project,
23
13
  aarLibraries: List<AndroidArchiveLibrary>,
24
14
  ) {
25
- val processManifestTask = variant.outputs.first().processManifestProvider.get()
26
- val variantName = variant.name
27
- processManifestTask.doLast {
28
- val buildDir = project.layout.buildDirectory.get()
29
- val manifestOutput =
30
- project.file(
31
- "$buildDir/intermediates/merged_manifest/$variantName/process${variantName.capitalized()}Manifest/AndroidManifest.xml",
32
- )
33
-
34
- val inputManifests = aarLibraries.map { it.getManifestFile() }
35
- mergeManifests(manifestOutput, inputManifests, manifestOutput, project.logger)
36
- }
37
- }
38
-
39
- private fun mergeManifests(
40
- mainManifestFile: File,
41
- secondaryManifestFiles: List<File>,
42
- outputFile: File,
43
- logger: Logger,
44
- ) {
45
- val iLogger: ILogger = GradleILogger(logger)
46
- val mergerInvoker = ManifestMerger2.newMerger(mainManifestFile, iLogger, ManifestMerger2.MergeType.LIBRARY)
47
- val manifestProviders = mutableListOf<ManifestProvider>()
48
-
49
- val filteredSecondaryManifests = secondaryManifestFiles.filter { it.exists() }
50
- filteredSecondaryManifests.forEach { file ->
51
- manifestProviders.add(
52
- object : ManifestProvider {
53
- override fun getManifest(): File = file.absoluteFile
54
-
55
- override fun getName(): String = file.name
56
- },
57
- )
58
- }
59
-
60
- mergerInvoker.addManifestProviders(manifestProviders)
61
- val mergingReport: MergingReport = mergerInvoker.merge()
62
-
63
- if (mergingReport.result.isError) {
64
- logger.error(mergingReport.reportString)
65
- mergingReport.log(iLogger)
66
- throw BuildException(mergingReport.reportString)
67
- }
68
-
69
- BufferedWriter(OutputStreamWriter(FileOutputStream(outputFile), "UTF-8")).use { writer ->
70
- writer.append(mergingReport.getMergedDocument(MergingReport.MergedManifestKind.MERGED))
71
- writer.flush()
72
- }
15
+ val capitalizedVariantName = variant.name.replaceFirstChar(Char::titlecase)
16
+ val taskProvider =
17
+ project.tasks.register(
18
+ "transform${capitalizedVariantName}BrownfieldMergedManifest",
19
+ MergeLibraryManifestTask::class.java,
20
+ ) { task ->
21
+ task.variantName.set(variant.name)
22
+ task.namespace.set(variant.namespace)
23
+ task.manifestPlaceholders.set(variant.manifestPlaceholders)
24
+ task.aarManifestFiles.from(aarLibraries.map { it.getManifestFile() })
25
+
26
+ // The exploded AAR manifests are generated out of band, so keep the transform
27
+ // ordered after the variant-specific explode task without reaching for old APIs.
28
+ task.dependsOn("explode${capitalizedVariantName}Aar")
29
+ }
30
+
31
+ variant.artifacts
32
+ .use(taskProvider)
33
+ .wiredWithFiles(
34
+ MergeLibraryManifestTask::inputManifest,
35
+ MergeLibraryManifestTask::outputManifest,
36
+ ).toTransform(SingleArtifact.MERGED_MANIFEST)
73
37
  }
74
38
  }
@@ -5,19 +5,12 @@ import org.gradle.api.Project
5
5
  import java.io.File
6
6
 
7
7
  object MergeProcessor {
8
- fun mergeClassesJarIntoClasses(
8
+ fun mergeClassesJarFilesIntoClasses(
9
9
  project: Project,
10
- androidLibraries: Collection<AndroidArchiveLibrary>,
10
+ classJarFiles: Collection<File>,
11
11
  folderOut: File,
12
12
  ) {
13
- val allJarFiles: MutableCollection<File> = ArrayList()
14
- val filteredLibs = getFilteredAarLibs(androidLibraries)
15
- filteredLibs.forEach {
16
- allJarFiles.add(it.getClassesJarFile())
17
- }
18
-
19
- val filteredAllJarFiles = allJarFiles.filter { it.exists() }
20
- filteredAllJarFiles.forEach { jarFile ->
13
+ classJarFiles.filter { it.exists() }.forEach { jarFile ->
21
14
  project.copy {
22
15
  it.from(project.zipTree(jarFile))
23
16
  it.into(folderOut)
@@ -25,28 +18,13 @@ object MergeProcessor {
25
18
  }
26
19
  }
27
20
 
28
- fun mergeLibsIntoClasses(
21
+ fun mergeClassesJarIntoClasses(
29
22
  project: Project,
30
23
  androidLibraries: Collection<AndroidArchiveLibrary>,
31
- jarFiles: Collection<File>,
32
- outputDir: File,
24
+ folderOut: File,
33
25
  ) {
34
- val allJarFiles: MutableCollection<File> = ArrayList()
35
- val filteredLibs = getFilteredAarLibs(androidLibraries)
36
- filteredLibs.forEach {
37
- allJarFiles.addAll(it.getLocalJars())
38
- }
39
-
40
- val filteredJarFiles = jarFiles.filter { it.exists() }
41
- filteredJarFiles.forEach { allJarFiles.add(it) }
42
-
43
- allJarFiles.forEach { jarFile ->
44
- project.copy {
45
- it.from(project.zipTree(jarFile))
46
- it.into(outputDir)
47
- it.exclude("META-INF/")
48
- }
49
- }
26
+ val classesJarFiles = getFilteredAarLibs(androidLibraries).map { it.getClassesJarFile() }
27
+ mergeClassesJarFilesIntoClasses(project, classesJarFiles, folderOut)
50
28
  }
51
29
 
52
30
  private fun getFilteredAarLibs(androidLibraries: Collection<AndroidArchiveLibrary>): Collection<AndroidArchiveLibrary> {
@@ -1,61 +1,24 @@
1
1
  package com.callstack.react.brownfield.processors
2
2
 
3
- import com.callstack.react.brownfield.exceptions.TaskNotFound
4
- import com.callstack.react.brownfield.shared.Logging
3
+ import com.callstack.react.brownfield.shared.ExplodeAarTask
5
4
  import com.callstack.react.brownfield.utils.Utils
6
5
  import org.gradle.api.Project
7
- import org.gradle.api.file.RegularFileProperty
8
6
  import org.gradle.api.tasks.TaskProvider
9
7
  import java.io.File
10
8
 
11
9
  class ProguardProcessor(val project: Project) {
12
- fun processConsumerFiles(
10
+ fun processFiles(
13
11
  proguardRules: List<File>,
14
12
  capitalizedVariantName: String,
13
+ explodeTask: TaskProvider<ExplodeAarTask>,
15
14
  ) {
16
15
  val mergeTaskName = "merge${capitalizedVariantName}ConsumerProguardFiles"
17
- val mergeFileTask = project.tasks.named(mergeTaskName)
18
-
19
- if (!mergeFileTask.isPresent) {
20
- throw TaskNotFound("Task $mergeTaskName not found")
21
- }
22
-
23
- mergeFileTask.get().doLast {
24
- val outputFile = it.outputs.files.singleFile
25
- doLast(proguardRules, outputFile)
26
- }
27
- }
28
-
29
- fun processGeneratedFiles(
30
- proguardRules: List<File>,
31
- capitalizedVariantName: String,
32
- ) {
33
- val mergeGenerateProguardTask: TaskProvider<*>?
34
- val mergeName = "merge${capitalizedVariantName}GeneratedProguardFiles"
35
- mergeGenerateProguardTask = project.tasks.named(mergeName)
36
-
37
- mergeGenerateProguardTask.get().doLast {
38
- val outputFile = it.outputs.files.singleFile
39
- doLast(proguardRules, outputFile)
40
- }
41
- }
42
-
43
- private fun doLast(
44
- files: List<File>,
45
- outputFile: File,
46
- ) {
47
- try {
48
- val outputFileToMerge =
49
- @Suppress("USELESS_IS_CHECK")
50
- if (outputFile is File) {
51
- outputFile
52
- } else {
53
- (outputFile as? RegularFileProperty)?.get()?.asFile
54
- ?: error("Invalid output file")
55
- }
56
- Utils.mergeFiles(files, outputFileToMerge)
57
- } catch (e: NoSuchFileException) {
58
- Logging.log(e)
16
+ project.tasks.matching { it.name == mergeTaskName }.configureEach { task ->
17
+ task.dependsOn(explodeTask)
18
+ task.doLast {
19
+ val outputFile = task.outputs.files.singleFile
20
+ Utils.mergeFiles(proguardRules, outputFile)
21
+ }
59
22
  }
60
23
  }
61
24
  }
@@ -1,26 +1,17 @@
1
1
  package com.callstack.react.brownfield.processors
2
2
 
3
- import com.android.build.gradle.api.LibraryVariant
4
- import com.callstack.react.brownfield.exceptions.TaskNotFound
3
+ import com.android.build.api.variant.LibraryVariant
5
4
  import com.callstack.react.brownfield.utils.AndroidArchiveLibrary
6
- import com.callstack.react.brownfield.utils.capitalized
7
- import org.gradle.api.Project
8
5
 
9
6
  object ResourceTaskProcessor {
10
7
  fun process(
11
8
  variant: LibraryVariant,
12
- project: Project,
13
9
  aarLibraries: List<AndroidArchiveLibrary>,
14
10
  ) {
15
- val taskPath = "generate${variant.name.capitalized()}Resources"
16
- val resourceGenTask = project.tasks.named(taskPath)
11
+ val resDirectories = aarLibraries.map { it.getResDir() }.filter { it.exists() }
17
12
 
18
- if (!resourceGenTask.isPresent) {
19
- throw TaskNotFound("Task $taskPath not found")
13
+ resDirectories.forEach { resDirectory ->
14
+ variant.sources.res?.addStaticSourceDirectory(resDirectory.path)
20
15
  }
21
-
22
- variant.registerGeneratedResFolders(
23
- project.files(aarLibraries.map { it.getResDir() }),
24
- )
25
16
  }
26
17
  }
@@ -1,61 +1,66 @@
1
1
  package com.callstack.react.brownfield.processors
2
2
 
3
- import com.callstack.react.brownfield.shared.BaseProject
4
- import com.callstack.react.brownfield.utils.AndroidArchiveLibrary
5
- import com.callstack.react.brownfield.utils.DirectoryManager
6
3
  import com.callstack.react.brownfield.utils.capitalized
7
- import org.gradle.api.file.ConfigurableFileCollection
8
- import java.io.File
9
- import java.nio.file.Files
10
- import java.nio.file.Path
11
- import java.nio.file.Paths
12
-
13
- class VariantHelper : BaseProject() {
14
- private fun getClassPathDirFiles(variantName: String): ConfigurableFileCollection {
15
- return project.files(
16
- "$buildDir/intermediates/javac/$variantName/compile${variantName.capitalized()}JavaWithJavac/classes",
17
- )
4
+ import org.gradle.api.Project
5
+ import org.gradle.api.Task
6
+ import org.gradle.api.tasks.TaskCollection
7
+
8
+ object VariantHelper {
9
+ fun getAsmTransformTaskName(capitalizedVariantName: String): String {
10
+ return "transform${capitalizedVariantName}ClassesWithAsm"
18
11
  }
19
12
 
20
- fun classesMergeTaskDoFirst(
21
- outputDir: File,
22
- variantName: String,
23
- ) {
24
- val pathsToDelete = mutableListOf<Path>()
25
- val javacDir = getClassPathDirFiles(variantName).first()
26
- project.fileTree(outputDir).forEach { path ->
27
- pathsToDelete.add(
28
- Paths.get(outputDir.absolutePath).relativize(Paths.get(path.absolutePath)),
29
- )
13
+ fun getBundledAssetsVariantName(
14
+ variantName: String?,
15
+ buildTypeName: String?,
16
+ isDebuggable: Boolean,
17
+ ): String {
18
+ require(!variantName.isNullOrEmpty()) {
19
+ "getBundledAssetsVariantName: Variant name cannot be empty"
30
20
  }
31
- outputDir.deleteRecursively()
32
- pathsToDelete.forEach { path ->
33
- Files.deleteIfExists(Paths.get("$javacDir.absolutePath/$path"))
21
+
22
+ require(!buildTypeName.isNullOrEmpty()) {
23
+ "getBundledAssetsVariantName: Build Type cannot be empty"
34
24
  }
35
- }
36
25
 
37
- fun classesMergeTaskDoLast(
38
- outputDir: File,
39
- aarLibraries: Collection<AndroidArchiveLibrary>,
40
- jarFiles: MutableList<File>,
41
- variantName: String,
42
- isMinifyEnabled: Boolean,
43
- ) {
44
- MergeProcessor.mergeClassesJarIntoClasses(project, aarLibraries, outputDir)
45
- if (isMinifyEnabled) {
46
- MergeProcessor.mergeLibsIntoClasses(project, aarLibraries, jarFiles, outputDir)
26
+ if (!isDebuggable) {
27
+ return variantName
47
28
  }
48
- val javacDir = getClassPathDirFiles(variantName).first()
49
- project.copy { copyTask ->
50
- copyTask.from(outputDir)
51
- copyTask.into(javacDir)
52
- copyTask.exclude("META-INF/")
29
+
30
+ if (variantName == buildTypeName) {
31
+ return "release"
53
32
  }
54
33
 
55
- project.copy { copyTask ->
56
- copyTask.from("${outputDir.absolutePath}/META-INF")
57
- copyTask.into(DirectoryManager.getKotlinMetaDirectory(variantName))
58
- copyTask.include("*.kotlin_module")
34
+ val capitalizedBuildTypeName = buildTypeName.capitalized()
35
+ return if (variantName.endsWith(capitalizedBuildTypeName)) {
36
+ "${variantName.removeSuffix(capitalizedBuildTypeName)}Release"
37
+ } else {
38
+ "release"
59
39
  }
60
40
  }
41
+
42
+ fun getExpoUpdatesResourcesTaskName(variantName: String): String {
43
+ return "create${variantName.capitalized()}UpdatesResources"
44
+ }
45
+
46
+ fun getKotlinCompileTask(
47
+ project: Project,
48
+ capitalizedVariantName: String,
49
+ ): TaskCollection<Task> {
50
+ return project.tasks.matching { it.name == "compile${capitalizedVariantName}Kotlin" }
51
+ }
52
+
53
+ fun getJavaCompileTask(
54
+ project: Project,
55
+ capitalizedVariantName: String,
56
+ ): TaskCollection<Task> {
57
+ return project.tasks.matching { it.name == "compile${capitalizedVariantName}JavaWithJavac" }
58
+ }
59
+
60
+ fun getAsmTransformTask(
61
+ project: Project,
62
+ capitalizedVariantName: String,
63
+ ): TaskCollection<Task> {
64
+ return project.tasks.matching { it.name == getAsmTransformTaskName(capitalizedVariantName) }
65
+ }
61
66
  }
@@ -1,8 +1,8 @@
1
1
  package com.callstack.react.brownfield.processors
2
2
 
3
- import com.android.build.gradle.internal.tasks.factory.dependsOn
4
- import com.callstack.react.brownfield.exceptions.TaskNotFound
3
+ import com.android.build.api.variant.LibraryVariant
5
4
  import com.callstack.react.brownfield.shared.ExplodeAarTask
5
+ import com.callstack.react.brownfield.shared.MergeClassesTask
6
6
  import com.callstack.react.brownfield.utils.AndroidArchiveLibrary
7
7
  import com.callstack.react.brownfield.utils.DirectoryManager
8
8
  import com.callstack.react.brownfield.utils.Extension
@@ -12,7 +12,6 @@ import org.gradle.api.Project
12
12
  import org.gradle.api.Task
13
13
  import org.gradle.api.UnknownTaskException
14
14
  import org.gradle.api.tasks.TaskProvider
15
- import java.io.File
16
15
 
17
16
  class VariantTaskProvider(val project: Project) {
18
17
  fun bundleTaskProvider(
@@ -28,77 +27,46 @@ class VariantTaskProvider(val project: Project) {
28
27
  }
29
28
  }
30
29
 
31
- fun processDataBinding(
32
- bundleTask: TaskProvider<Task>,
33
- aarLibraries: Collection<AndroidArchiveLibrary>,
34
- variantName: String,
35
- ) {
36
- bundleTask.configure { task ->
37
- task.doLast {
38
- aarLibraries.forEach {
39
- val dataBindingFolder = it.getDataBindingFolder()
40
- if (dataBindingFolder.exists()) {
41
- val filePath = getReBundleFilePath(dataBindingFolder.name, variantName)
42
- File(filePath).mkdirs()
43
- project.copy { copyTask ->
44
- copyTask.from(dataBindingFolder)
45
- copyTask.into(filePath)
46
- }
47
- }
48
-
49
- val dataBindingLogFolder = it.getDataBindingLogFolder()
50
- if (dataBindingLogFolder.exists()) {
51
- val filePath = getReBundleFilePath(dataBindingLogFolder.name, variantName)
52
- File(filePath).mkdirs()
53
- project.copy { copyTask ->
54
- copyTask.from(dataBindingLogFolder)
55
- copyTask.into(filePath)
56
- }
57
- }
58
- }
59
- }
60
- }
61
- }
62
-
63
- private fun getReBundleFilePath(
64
- folderName: String,
65
- variantName: String,
66
- ) = "${DirectoryManager.getReBundleDirectory(
67
- variantName,
68
- ).path}/$folderName"
69
-
70
30
  fun preBuildTaskByVariant(
71
- variantName: String,
72
- buildTypeName: String,
73
- isVariantDebuggable: Boolean,
31
+ variant: LibraryVariant,
74
32
  explodeAarTask: TaskProvider<ExplodeAarTask>,
75
33
  ) {
76
- val preBuildTaskPath = "pre${variantName.capitalized()}Build"
77
- val preBuildTask = project.tasks.named(preBuildTaskPath)
78
-
79
- if (!preBuildTask.isPresent) {
80
- throw TaskNotFound("Can not find $preBuildTaskPath task")
81
- }
82
-
83
- preBuildTask.dependsOn(explodeAarTask)
84
-
34
+ val variantName = variant.name
85
35
  val bundledAssetsVariantName =
86
- Utils.getBundledAssetsVariantName(
36
+ VariantHelper.getBundledAssetsVariantName(
87
37
  variantName = variantName,
88
- buildTypeName = buildTypeName,
89
- isDebuggable = isVariantDebuggable,
38
+ buildTypeName = variant.buildType,
39
+ isDebuggable = variant.debuggable,
90
40
  )
91
41
  val capitalizedBundledAssetsVariantName = bundledAssetsVariantName.capitalized()
92
42
 
93
43
  val projectExt = project.extensions.getByType(Extension::class.java)
94
44
  val appProject = project.rootProject.project(projectExt.appProjectName)
95
- preBuildTask.dependsOn("${appProject.path}:createBundle${capitalizedBundledAssetsVariantName}JsAndAssets")
96
45
 
97
- if (Utils.isExpoProject(project)) {
98
- val updatesResourcesTaskName = Utils.getExpoUpdatesResourcesTaskName(variantName)
99
- if (Utils.hasExpoUpdates(appProject, variantName)) {
100
- preBuildTask.dependsOn("${appProject.path}:$updatesResourcesTaskName")
101
- }
46
+ val jsBundleTaskName = "${appProject.path}:createBundle${capitalizedBundledAssetsVariantName}JsAndAssets"
47
+
48
+ variant.lifecycleTasks.registerPreBuild(explodeAarTask, jsBundleTaskName)
49
+ if (Utils.isExpoProject(project) && Utils.hasExpoUpdates(appProject, variantName)) {
50
+ val updatesResourcesTaskName = VariantHelper.getExpoUpdatesResourcesTaskName(variantName)
51
+ variant.lifecycleTasks.registerPreBuild("${appProject.path}:$updatesResourcesTaskName")
52
+ }
53
+ }
54
+
55
+ fun mergeClasses(
56
+ aarLibraries: Collection<AndroidArchiveLibrary>,
57
+ explodeTasks: TaskProvider<ExplodeAarTask>,
58
+ variantName: String,
59
+ ): TaskProvider<MergeClassesTask> {
60
+ val capitalizedVariantName = variantName.capitalized()
61
+ val mergeClassesTaskName = "mergeClasses$capitalizedVariantName"
62
+
63
+ return project.tasks.register(mergeClassesTaskName, MergeClassesTask::class.java) {
64
+ it.dependsOn(explodeTasks)
65
+ it.dependsOn(VariantHelper.getKotlinCompileTask(project, capitalizedVariantName))
66
+ it.dependsOn(VariantHelper.getJavaCompileTask(project, capitalizedVariantName))
67
+ it.variantName.set(variantName)
68
+ it.inputClassesJars.from(aarLibraries.map { aarLibrary -> aarLibrary.getClassesJarFile() })
69
+ it.outputDir.set(DirectoryManager.getMergeClassDirectory(variantName))
102
70
  }
103
71
  }
104
72
  }
@@ -1,10 +1,10 @@
1
- @file:Suppress("DEPRECATION")
2
-
3
1
  package com.callstack.react.brownfield.shared
4
2
 
5
- import com.android.build.gradle.LibraryExtension
6
- import com.android.build.gradle.api.LibraryVariant
3
+ import com.android.build.api.dsl.LibraryExtension
4
+ import com.android.build.api.dsl.LibraryProductFlavor
5
+ import com.android.build.api.variant.LibraryVariant
7
6
  import com.callstack.react.brownfield.processors.VariantTaskProvider
7
+ import com.callstack.react.brownfield.utils.capitalized
8
8
  import org.gradle.api.Project
9
9
  import org.gradle.api.Task
10
10
  import org.gradle.api.tasks.TaskProvider
@@ -13,34 +13,79 @@ class BundleTaskProvider(private val variantTaskProvider: VariantTaskProvider) {
13
13
  fun getBundleTask(
14
14
  project: Project,
15
15
  variant: LibraryVariant,
16
- ): TaskProvider<Task>? {
17
- val androidExtension = project.extensions.getByType(LibraryExtension::class.java)
18
-
19
- // Find the first variant in the library that matches our criteria
20
- val matchedVariant =
21
- androidExtension.libraryVariants.find { libraryVariant ->
22
- // 1. Try Simple Match
23
- if (libraryVariant.name == variant.name || libraryVariant.name == variant.buildType.name) {
24
- return@find true
25
- }
16
+ missingDimensionStrategies: List<String>,
17
+ ): TaskProvider<Task> {
18
+ val taskName = resolveTaskName(project, variant, missingDimensionStrategies)
19
+ return variantTaskProvider.bundleTaskProvider(project, taskName)
20
+ }
21
+
22
+ private fun resolveTaskName(
23
+ project: Project,
24
+ variant: LibraryVariant,
25
+ missingDimensionStrategies: List<String>,
26
+ ): String {
27
+ val androidComponent = project.extensions.findByType(LibraryExtension::class.java) ?: return variant.name
26
28
 
27
- // 2. Try Dimension Strategy Match
28
- val flavor = variant.productFlavors.firstOrNull() ?: variant.mergedFlavor
29
- val strategies =
30
- runCatching {
31
- androidExtension.productFlavors.getByName(flavor.name).missingDimensionStrategies
32
- }.getOrNull() ?: return@find false
29
+ for (buildType in androidComponent.buildTypes) {
30
+ if (buildType.name != variant.name && buildType.name != variant.buildType) {
31
+ continue
32
+ }
33
33
 
34
- strategies.any { (dimension, strategy) ->
35
- val fallbacks = listOf(strategy.requested) + strategy.fallbacks
36
- val libFlavor = libraryVariant.productFlavors.firstOrNull() ?: libraryVariant.mergedFlavor
34
+ if (androidComponent.productFlavors.isEmpty()) {
35
+ return buildType.name.capitalized()
36
+ }
37
37
 
38
- dimension == libFlavor.dimension &&
39
- fallbacks.contains(libFlavor.name) &&
40
- variant.buildType.name == libraryVariant.buildType.name
38
+ val flavorNames = androidComponent.productFlavors.map { fl -> fl.name }
39
+ for (productFlavor in androidComponent.productFlavors) {
40
+ handleMissingDimensionStrategies(missingDimensionStrategies, project, flavorNames, productFlavor)
41
+ val flavorName = missingDimensionStrategies[1]
42
+ if (productFlavor.name != flavorName) {
43
+ continue
41
44
  }
45
+
46
+ return "${productFlavor.name.capitalized()}${buildType.name.capitalized()}"
42
47
  }
48
+ }
43
49
 
44
- return matchedVariant?.let { variantTaskProvider.bundleTaskProvider(project, it.name) }
50
+ return variant.name
51
+ }
52
+
53
+ private fun handleMissingDimensionStrategies(
54
+ missingDimensionStrategies: List<String>,
55
+ project: Project,
56
+ flavorNames: List<String>,
57
+ productFlavor: LibraryProductFlavor,
58
+ ) {
59
+ if (missingDimensionStrategies.isEmpty()) {
60
+ throw MissingDimensionStrategiesException(getErrorMessage(project.name))
61
+ }
62
+
63
+ val dimension = missingDimensionStrategies[0]
64
+ if (productFlavor.dimension != dimension) {
65
+ throw DimensionMismatchException(
66
+ "Ensure the provided dimension matches the ${project.name}'s dimension. Required dimension: $dimension",
67
+ )
68
+ }
69
+
70
+ val flavorName = missingDimensionStrategies[1]
71
+ if (!flavorNames.contains(flavorName)) {
72
+ throw FlavorMismatchException(
73
+ "Ensure the provided flavor matches the ${project.name}'s flavor. Required flavor(s): $flavorNames",
74
+ )
75
+ }
76
+ }
77
+
78
+ private fun getErrorMessage(projectName: String): String {
79
+ return """
80
+ Provide `missingDimensionStrategies` for $projectName:
81
+ If using Expo, provide the `android.expo.missingDimensionStrategies` property from Brownfield Config.
82
+ If using Bare React Native, provide the `reactBrownfield.missingDimensionStrategies` property.
83
+ """.trimIndent()
45
84
  }
46
85
  }
86
+
87
+ class MissingDimensionStrategiesException(message: String) : IllegalStateException(message)
88
+
89
+ class DimensionMismatchException(message: String) : IllegalArgumentException(message)
90
+
91
+ class FlavorMismatchException(message: String) : IllegalArgumentException(message)
@@ -38,7 +38,6 @@ object Constants {
38
38
  const val PROJECT_ID = "com.callstack.react.brownfield"
39
39
  const val PLUGIN_NAME = "react-brownfield"
40
40
 
41
- const val RE_BUNDLE_FOLDER = "aar_rebundle"
42
41
  const val INTERMEDIATES_TEMP_DIR = PLUGIN_NAME
43
42
 
44
43
  val BROWNFIELD_EXPO_TRANSITIVE_DEPS_WHITELISTED_MODULES_FOR_DISCOVERY =