- 
                Notifications
    You must be signed in to change notification settings 
- Fork 7.4k
dataconnect: integrate codegen into the gradle build #2569
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
        
          
                gradle/libs.versions.toml
              
                Outdated
          
        
      | composeBom = "2024.11.00" | ||
| googleServices = "4.4.2" | ||
| composeNavigation = "2.8.4" | ||
| ktfmt = "0.43" | 
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(No action required)
We use ktlint in this repo, but I've considered moving to ktfmt so that it aligns with the SDK formatting.
I'm happy to move forward with ktfmt only applied to dataconnect in this PR and we can apply to other modules and remove ktlint in a follow-up PR.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ahh ok. Yeah I think this isn't the PR to change the code formatting tool. I'll switch to ktlint.
| # Use an arbitrary directory for generating the code, as the | ||
| # "com.google.firebase.example.dataconnect.gradle" custom Gradle plugin applied by | ||
| # app/build.gradle.kts will look after generating the code on-demand into the | ||
| # appropriate directory. | 
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Where does it generate? I checked out your repo and tried running the ./gradlew generateDebugDataConnectSources command but couldn't see the generated files.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll update the comment to be more clear about where the code gets generated by gradle.
In the meantime, if you run ./gradlew --info generateDebugDataConnectSources (i.e. add the --info argument) the logs state the directory into which the code is generated.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh, cool, I see it in quickstart-android/dataconnect/app/build/generated/java/generateDebugDataConnectSources/com/google/firebase/dataconnect/movies
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Comment updated to this:
... app/build.gradle.kts will look after generating the code on-demand into the directory prescribed by Gradle (e.g. app/build/generated/java/generateDebugDataConnectSources).
…view feedback Co-authored-by: Rosário P. Fernandes <[email protected]>
Co-authored-by: Rosário P. Fernandes <[email protected]>
…mple of the directory into which the code may be generated
… (still needs to implement verify)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(oops, forgot to publish my comments 2 weeks ago [facepalm])
| # Use an arbitrary directory for generating the code, as the | ||
| # "com.google.firebase.example.dataconnect.gradle" custom Gradle plugin applied by | ||
| # app/build.gradle.kts will look after generating the code on-demand into the | ||
| # appropriate directory. | 
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Comment updated to this:
... app/build.gradle.kts will look after generating the code on-demand into the directory prescribed by Gradle (e.g. app/build/generated/java/generateDebugDataConnectSources).
        
          
                gradle/libs.versions.toml
              
                Outdated
          
        
      | composeBom = "2024.11.00" | ||
| googleServices = "4.4.2" | ||
| composeNavigation = "2.8.4" | ||
| ktfmt = "0.43" | 
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ahh ok. Yeah I think this isn't the PR to change the code formatting tool. I'll switch to ktlint.
| This PR is on hold for now. It was just taking me wayyyy to long and I needed to timebox it. Anything gradle related usually takes forever! | 
This PR adds a custom gradle plugin to the "dataconnect" project to hook into the gradle build and generate the Data Connect source code automatically as part of the build. There is no longer a requirement to manually download and launch the Data Connect emulator just to build the project. This behaves very similarly to the protobuf gradle plugin (https://github.com/google/protobuf-gradle-plugin) and how it compiles the
.protofiles to java/kt files on-demand when the project is built. This also unblocks compiling the dataconnect module in GitHub CI.The plugin first creates a node project directory (by creating an empty directory that contains an empty package.json) and installs the configured version of firebase-tools into it by running
npm install. Then, it uses that firebase-tools to run thedataconnect:sdk:generatesubcommand. In order to control where the generated code gets placed, a copy of the dataconnect.yaml et al files is made, and the connector.yaml files are modified to only produce kotlin connectors and to put them into the directory of the gradle plugin's choosing. All of this is done in the "build" directory, and, therefore, is wiped out by a "gradle clean".As a nice side effect, the GitHub Actions CI can now compile dataconnect just fine. Therefore, this PR also removes the hacks that opted dataconnect out of the CI.
The following new tasks are now present in the
:dataconnect:appmodule:setupFirebaseToolsForDataConnectdataconnect/app/build/dataconnect/firebase-toolswith a single file in it, an emptypackage.json.npm install [email protected]in that directory (the version is configured in build.gradle.kts).generateDebugDataConnectSourcesandgenerateReleaseDataConnectSourcessetupFirebaseToolsForDataConnecttask to set up thefirebasecommanddataconnect/dataconnectintodataconnect/app/build/dataconnect/variants/{debug,release}/configgeneratesection, except forkotlinSdk. This is because since we're building the kotlin SDK, we don't want to generate code for other SDKs.outputDirof thekotlinSdkto use the directory specified by the gradle plugin for placing the generated code. This is because gradle dictates where the generated code is to go and this directory can't be known in advance and hardcoded into the file. Moreover, the directories are different for the "debug" and "release" builds.firebase dataconnect:sdk:generateto generate the code into the directory dictated by gradle.This plugin is configured by a new "extension" added to
dataconnect/app/build.gradle.kts. It looks like this:dataconnect { // The version of https://www.npmjs.com/package/firebase-tools to use to perform the // Data Connect code generation. firebaseToolsVersion = "13.25.0" // The directory that contains dataconnect.yaml to use as input when performing // the Data Connect code generation. dataConnectConfigDir = file("../dataconnect") }This gradle plugin is a proof-of-concept and isn't quite production ready. If it proves to be valuable, customers can at least copy/paste it into their own Android projects. Or, we could make it an "official" plugin. There is even a way to remove the need for node altogether, by just calling the data connect toolkit cli binary directly (without needing to install firebase-tools). This plugin was largely based on my experience writing a similar gradle plugin in the dataconnect android sdk itself: https://github.com/firebase/firebase-android-sdk/blob/866e6bd246fde0e54fdeb5f5d0c043632edf4161/firebase-dataconnect/gradleplugin/plugin/src/main/kotlin/com/google/firebase/dataconnect/gradle/plugin/DataConnectGradlePlugin.kt.