From fb28f29d445220a75da9dd86d3eb85fa26a857e3 Mon Sep 17 00:00:00 2001 From: Maciej Stosio Date: Tue, 4 Jun 2024 15:26:11 +0200 Subject: [PATCH 1/5] feat: add task to automatically copy codegen files to paper --- Example/android/gradle.properties | 2 + FabricExample/android/gradle.properties | 2 + TestsExample/android/gradle.properties | 2 + android/build.gradle | 76 +++++++++++++++++++++++++ android/gradle.properties | 5 ++ 5 files changed, 87 insertions(+) create mode 100644 android/gradle.properties diff --git a/Example/android/gradle.properties b/Example/android/gradle.properties index a46a5b90f..1a8de6684 100644 --- a/Example/android/gradle.properties +++ b/Example/android/gradle.properties @@ -39,3 +39,5 @@ newArchEnabled=false # Use this property to enable or disable the Hermes JS engine. # If set to false, you will be using JSC instead. hermesEnabled=true + +isRNSVGExampleApp=true diff --git a/FabricExample/android/gradle.properties b/FabricExample/android/gradle.properties index 99fc223ed..ff79b10e5 100644 --- a/FabricExample/android/gradle.properties +++ b/FabricExample/android/gradle.properties @@ -39,3 +39,5 @@ newArchEnabled=true # Use this property to enable or disable the Hermes JS engine. # If set to false, you will be using JSC instead. hermesEnabled=true + +isRNSVGExampleApp=true diff --git a/TestsExample/android/gradle.properties b/TestsExample/android/gradle.properties index a46a5b90f..1a8de6684 100644 --- a/TestsExample/android/gradle.properties +++ b/TestsExample/android/gradle.properties @@ -39,3 +39,5 @@ newArchEnabled=false # Use this property to enable or disable the Hermes JS engine. # If set to false, you will be using JSC instead. hermesEnabled=true + +isRNSVGExampleApp=true diff --git a/android/build.gradle b/android/build.gradle index 212df94ce..dc302f28e 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -93,3 +93,79 @@ repositories { dependencies { implementation 'com.facebook.react:react-native:+' } + +def isRNSVGExampleApp() { + return project.hasProperty('isRNSVGExampleApp') && project.property('isRNSVGExampleApp') == "true" +} + +def getAbsoluteCodegenArtifactsPaperDestination() { + if (!project.hasProperty('codegenArtifactsPaperDestination')) { + throw new Exception('[RNSVG] Please fill codegenArtifactsPaperDestination variable in android/gradle.properties correct path to paper paper destination') + } + + return "${project.rootDir}/../../${project.property('codegenArtifactsPaperDestination')}" +} + +def getAbsoluteCodegenArtifactsSource() { + if (!project.hasProperty('codegenArtifactsSource')) { + throw new Exception('[RNSVG] Please fill codegenArtifactsSource variable in android/gradle.properties correct path to codegenerated artifacts') + } + + return "${project.rootDir}/../../${project.property('codegenArtifactsSource')}" +} + + +tasks.register("copyCodegenArtifacts") { + group 'After build tasks' + description 'Tasks which copy codegen artifacts to paper architecture' + + if (!isRNSVGExampleApp() || !isNewArchitectureEnabled()) { + return + } + + dependsOn tasks.generateCodegenArtifactsFromSchema + + doLast { + + def absoluteCodegenArtifactsPaperDestination = getAbsoluteCodegenArtifactsPaperDestination() + def absoluteCodegenArtifactsSource = getAbsoluteCodegenArtifactsSource() + + def existingFiles = fileTree(absoluteCodegenArtifactsPaperDestination).matching { + include '**/*.java' + } + + def generatedFiles = fileTree(absoluteCodegenArtifactsSource).matching { + include '**/*.java' + } + + def existingFilesMap = [:] + + existingFiles.forEach { existingFile -> + existingFilesMap[existingFile.name] = 1 + } + + generatedFiles.forEach { generatedFile -> + if (!existingFilesMap.containsKey(generatedFile.name)) { + logger.warn("[RNSVG] ${generatedFile.name} not found in paper dir, if it's used in Android you need to copy it manually and implement yourself before using auto-copy feature") + } + } + + if (existingFiles.size() == 0) { + logger.warn("[RNSVG] Paper destination with codegen interfaces is empty. This might be okay if you don't have any interfaces/delegates used in Android, if that's not the case please check if codegenArtifactsPaperDestination in android/gradle.properties is correct") + } + + if (existingFiles.size() > generatedFiles.size()) { + throw new Exception("[RNSVG] Number od generated artifacts should be greather then or equal to paper interfaces. Please check if codegenArtifactsSource in android/gradle.properties is correct") + } + + copy { + from absoluteCodegenArtifactsSource + include existingFiles.collect { it.name } + into absoluteCodegenArtifactsPaperDestination + } + } +} + +if (isRNSVGExampleApp() && isNewArchitectureEnabled()) { + tasks.generateCodegenArtifactsFromSchema.finalizedBy('copyCodegenArtifacts') +} diff --git a/android/gradle.properties b/android/gradle.properties new file mode 100644 index 000000000..496cfc25d --- /dev/null +++ b/android/gradle.properties @@ -0,0 +1,5 @@ +# Path to codegen artifacts, used for task (copyCodegenArtifacts) that automates copying them to paper destination +codegenArtifactsSource=android/build/generated/source/codegen/java/com/facebook/react/viewmanagers +# Destination to peper path where codegen interfaces should stored and then implemented, so we have consistency in both architectures. +# Used for task (copyCodegenArtifacts) that automates copying those interfaces/delegates when codegen is run +codegenArtifactsPaperDestination=android/src/paper/java/com/facebook/react/viewmanagers From be5c449d450eb184357be1005cb6a42808467c04 Mon Sep 17 00:00:00 2001 From: Maciej Stosio Date: Tue, 4 Jun 2024 15:33:37 +0200 Subject: [PATCH 2/5] chore: update comment --- android/gradle.properties | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/android/gradle.properties b/android/gradle.properties index 496cfc25d..bea10eb1e 100644 --- a/android/gradle.properties +++ b/android/gradle.properties @@ -1,5 +1,6 @@ -# Path to codegen artifacts, used for task (copyCodegenArtifacts) that automates copying them to paper destination +# Path to codegen output directory with this library view manager's interfaces & delegates. Used by `copyCodegenArtifacts` task that helps to synchronise newly generated files with their Paper conterparts. codegenArtifactsSource=android/build/generated/source/codegen/java/com/facebook/react/viewmanagers -# Destination to peper path where codegen interfaces should stored and then implemented, so we have consistency in both architectures. + +# Path to directory with view manager's interfaces & delegates used while running on Paper architecture. This property is used as output path for `copyCodegenArtifacts` task. # Used for task (copyCodegenArtifacts) that automates copying those interfaces/delegates when codegen is run codegenArtifactsPaperDestination=android/src/paper/java/com/facebook/react/viewmanagers From efe882af1e1d1a17c01f4f6a327bddb0a360500c Mon Sep 17 00:00:00 2001 From: Maciej Stosio Date: Wed, 5 Jun 2024 08:48:52 +0200 Subject: [PATCH 3/5] fix: correct misspelings in gradle task for automate copy --- android/build.gradle | 8 ++++---- android/gradle.properties | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/android/build.gradle b/android/build.gradle index dc302f28e..c55a992b9 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -100,7 +100,7 @@ def isRNSVGExampleApp() { def getAbsoluteCodegenArtifactsPaperDestination() { if (!project.hasProperty('codegenArtifactsPaperDestination')) { - throw new Exception('[RNSVG] Please fill codegenArtifactsPaperDestination variable in android/gradle.properties correct path to paper paper destination') + throw new Exception('[RNSVG] Please fill codegenArtifactsPaperDestination variable in android/gradle.properties to point to the correct path to generated specs for paper') } return "${project.rootDir}/../../${project.property('codegenArtifactsPaperDestination')}" @@ -108,7 +108,7 @@ def getAbsoluteCodegenArtifactsPaperDestination() { def getAbsoluteCodegenArtifactsSource() { if (!project.hasProperty('codegenArtifactsSource')) { - throw new Exception('[RNSVG] Please fill codegenArtifactsSource variable in android/gradle.properties correct path to codegenerated artifacts') + throw new Exception('[RNSVG] Please fill codegenArtifactsSource variable in android/gradle.properties to point to the correct path to generated specs for paper') } return "${project.rootDir}/../../${project.property('codegenArtifactsSource')}" @@ -117,7 +117,7 @@ def getAbsoluteCodegenArtifactsSource() { tasks.register("copyCodegenArtifacts") { group 'After build tasks' - description 'Tasks which copy codegen artifacts to paper architecture' + description 'Task which copies codegen artifacts to paper architecture' if (!isRNSVGExampleApp() || !isNewArchitectureEnabled()) { return @@ -155,7 +155,7 @@ tasks.register("copyCodegenArtifacts") { } if (existingFiles.size() > generatedFiles.size()) { - throw new Exception("[RNSVG] Number od generated artifacts should be greather then or equal to paper interfaces. Please check if codegenArtifactsSource in android/gradle.properties is correct") + throw new Exception("[RNSVG] Number od generated artifacts should be greater than or equal to paper interfaces. Please check if codegenArtifactsSource in android/gradle.properties is correct") } copy { diff --git a/android/gradle.properties b/android/gradle.properties index bea10eb1e..0fe6bbd9a 100644 --- a/android/gradle.properties +++ b/android/gradle.properties @@ -1,6 +1,6 @@ -# Path to codegen output directory with this library view manager's interfaces & delegates. Used by `copyCodegenArtifacts` task that helps to synchronise newly generated files with their Paper conterparts. +# Path to codegen output directory with this library view managers' interfaces & delegates. Used by `copyCodegenArtifacts` task that helps to synchronize newly generated files with their Paper counterparts. codegenArtifactsSource=android/build/generated/source/codegen/java/com/facebook/react/viewmanagers -# Path to directory with view manager's interfaces & delegates used while running on Paper architecture. This property is used as output path for `copyCodegenArtifacts` task. +# Path to directory with view managers' interfaces & delegates used while running on Paper architecture. This property is used as the output path for `copyCodegenArtifacts` task. # Used for task (copyCodegenArtifacts) that automates copying those interfaces/delegates when codegen is run codegenArtifactsPaperDestination=android/src/paper/java/com/facebook/react/viewmanagers From 2bd2482a80ecef6a7b6dcd369f3ab07dfdeecc79 Mon Sep 17 00:00:00 2001 From: Maciej Stosio Date: Mon, 10 Jun 2024 14:32:12 +0200 Subject: [PATCH 4/5] chore: move changes from gesture-handler --- .github/workflows/check-paper-integrity.yml | 48 +++++++++++++++++++++ android/build.gradle | 42 +++++++++++++++--- android/gradle.properties | 2 +- package.json | 3 +- 4 files changed, 86 insertions(+), 9 deletions(-) create mode 100644 .github/workflows/check-paper-integrity.yml diff --git a/.github/workflows/check-paper-integrity.yml b/.github/workflows/check-paper-integrity.yml new file mode 100644 index 000000000..bbd0c4019 --- /dev/null +++ b/.github/workflows/check-paper-integrity.yml @@ -0,0 +1,48 @@ +name: Test Paper Architecture integrity +on: [pull_request] +jobs: + check: + if: github.repository == 'software-mansion/react-native-gesture-handler' + runs-on: ubuntu-latest + concurrency: + group: kotlin-lint-${{ github.ref }} + cancel-in-progress: true + steps: + - name: checkout + uses: actions/checkout@v2 + + - name: Use Java 17 + uses: actions/setup-java@v3 + with: + distribution: 'oracle' + java-version: '17' + + - name: Use Node.js 18 + uses: actions/setup-node@v2 + with: + node-version: 18 + cache: 'yarn' + + - uses: actions/cache@v2 + with: + path: '**/node_modules' + key: ${{ runner.os }}-modules-${{ hashFiles('**/yarn.lock') }} + + - name: Install node dependencies + run: yarn install --frozen-lockfile + + - name: Install node dependencies of FabricExample + run: (cd FabricExample && yarn install --frozen-lockfile) + + - name: Restore build from cache + uses: actions/cache@v3 + with: + path: | + ~/.gradle/caches + ~/.gradle/wrapper + android/build + android/.gradle + key: ${{ runner.os }}-kotlin-lint-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties', 'android/build.gradle') }} + + - name: Check old arch integrity + run: yarn checkIntegrity diff --git a/android/build.gradle b/android/build.gradle index c55a992b9..21020a4ea 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -108,14 +108,14 @@ def getAbsoluteCodegenArtifactsPaperDestination() { def getAbsoluteCodegenArtifactsSource() { if (!project.hasProperty('codegenArtifactsSource')) { - throw new Exception('[RNSVG] Please fill codegenArtifactsSource variable in android/gradle.properties to point to the correct path to generated specs for paper') + throw new Exception('[RNSVG] Please fill codegenArtifactsSource variable in android/gradle.properties to point to the correct path to codegenerated artifacts') } return "${project.rootDir}/../../${project.property('codegenArtifactsSource')}" } -tasks.register("copyCodegenArtifacts") { +tasks.register('copyCodegenArtifacts') { group 'After build tasks' description 'Task which copies codegen artifacts to paper architecture' @@ -146,16 +146,20 @@ tasks.register("copyCodegenArtifacts") { generatedFiles.forEach { generatedFile -> if (!existingFilesMap.containsKey(generatedFile.name)) { - logger.warn("[RNSVG] ${generatedFile.name} not found in paper dir, if it's used in Android you need to copy it manually and implement yourself before using auto-copy feature") + logger.warn("[RNSVG] ${generatedFile.name} not found in paper dir, if it's used on Android you need to copy it manually and implement yourself before using auto-copy feature.") } } if (existingFiles.size() == 0) { - logger.warn("[RNSVG] Paper destination with codegen interfaces is empty. This might be okay if you don't have any interfaces/delegates used in Android, if that's not the case please check if codegenArtifactsPaperDestination in android/gradle.properties is correct") + logger.warn("[RNSVG] Paper destination with codegen interfaces is empty. This might be okay if you don't have any interfaces/delegates used on Android, but if that's not the case please check if codegenArtifactsPaperDestination property in android/gradle.properties is correct.") } - if (existingFiles.size() > generatedFiles.size()) { - throw new Exception("[RNSVG] Number od generated artifacts should be greater than or equal to paper interfaces. Please check if codegenArtifactsSource in android/gradle.properties is correct") + existingFiles.forEach { existingFile -> + def generatedFile = new File("${absoluteCodegenArtifactsSource}/${existingFile.name}") + + if (!generatedFile.exists()) { + logger.warn("[RNSVG] ${existingFile.name} file does not exist in codegen artifacts source destination. Please check if you still need this interface/delagete.") + } } copy { @@ -166,6 +170,30 @@ tasks.register("copyCodegenArtifacts") { } } -if (isRNSVGExampleApp() && isNewArchitectureEnabled()) { +if (isRNSVGExampleApp() && isNewArchitectureEnabled() && !project.hasProperty('skipCodegenCopyTask')) { tasks.generateCodegenArtifactsFromSchema.finalizedBy('copyCodegenArtifacts') } + +tasks.register('checkIntegrityBetweenArchitectures') { + group 'Verification tasks' + description 'Task to check integrity between fabric and paper architecture in terms of codegen generated interfaces/delegates' + + if (isRNSVGExampleApp()) { + return + } + + def absoluteCodegenArtifactsPaperDestination = "../${project.property('codegenArtifactsPaperDestination')}" + def absoluteCodegenArtifactsSource = "../${project.property('codegenArtifactsSource')}" + + def existingFiles = fileTree(absoluteCodegenArtifactsPaperDestination).matching { + include '**/*.java' + } + + existingFiles.forEach { existingFile -> + def generatedFile = new File("${absoluteCodegenArtifactsSource}/${existingFile.name}") + + if (existingFile.text != generatedFile.text) { + throw new RuntimeException("RNSVG] The source of ${existingFile.name} does not match with the one generated by codegen. Please check if you commited changes produced by copyCodegenArtifacts task.") + } + } +} diff --git a/android/gradle.properties b/android/gradle.properties index 0fe6bbd9a..4b37d560a 100644 --- a/android/gradle.properties +++ b/android/gradle.properties @@ -2,5 +2,5 @@ codegenArtifactsSource=android/build/generated/source/codegen/java/com/facebook/react/viewmanagers # Path to directory with view managers' interfaces & delegates used while running on Paper architecture. This property is used as the output path for `copyCodegenArtifacts` task. -# Used for task (copyCodegenArtifacts) that automates copying those interfaces/delegates when codegen is run +# Used by copyCodegenArtifacts task that automates copying those interfaces/delegates after codegen is run. codegenArtifactsPaperDestination=android/src/paper/java/com/facebook/react/viewmanagers diff --git a/package.json b/package.json index 1d438996a..510151ed3 100644 --- a/package.json +++ b/package.json @@ -56,7 +56,8 @@ "prepare": "npm run bob && husky install", "release": "npm login && release-it", "test": "npm run lint && npm run tsc", - "tsc": "tsc --noEmit" + "tsc": "tsc --noEmit", + "checkIntegrity": "(cd ./FabricExample/android && ./gradlew generateCodegenArtifactsFromSchema -PskipCodegenCopyTask) && (cd ./android && ./gradlew checkIntegrityBetweenArchitectures)" }, "peerDependencies": { "react": "*", From b5095e45aa5fb0ddc3c53ab678b243dbf2e1571c Mon Sep 17 00:00:00 2001 From: Maciej Stosio Date: Mon, 10 Jun 2024 14:34:16 +0200 Subject: [PATCH 5/5] chore: remove GH if --- .github/workflows/check-paper-integrity.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/check-paper-integrity.yml b/.github/workflows/check-paper-integrity.yml index bbd0c4019..bfae85bca 100644 --- a/.github/workflows/check-paper-integrity.yml +++ b/.github/workflows/check-paper-integrity.yml @@ -2,7 +2,6 @@ name: Test Paper Architecture integrity on: [pull_request] jobs: check: - if: github.repository == 'software-mansion/react-native-gesture-handler' runs-on: ubuntu-latest concurrency: group: kotlin-lint-${{ github.ref }}