Skip to content

[Document] Usage of Dart-Define variables in gradle scripts #100292

Closed
flutter/website
#8417

Description

@Sese-Schneider

While creating integration tests for our Flutter application, we're facing a blocking issue:

Following the official flutter documentation for integration testing, in the section to automate the tests on Firebase Test Lab, its stated to build the app with gradle.

pushd android
# flutter build generates files in android/ for building the app
flutter build apk
./gradlew app:assembleAndroidTest
./gradlew app:assembleDebug -Ptarget=integration_test/<name>_test.dart
popd

Unfortuantely, its not stated on how to include --dart-define variables into the script so that the created APK is build with the variable defined.

According to a stackoverflow thread, I've tried setting the variable in gradle.properties, with no effect.

As nothing in this matter is documented, I assume its not possible and therefor file this issue.
If it is possible, how can we pass the dart-define to the gradle build? Adjusting the documentation here might be helpful :)

Expected results:
Integration testable APK with a dart-define variable modified in its source code.

Actual results:
The APK only has default behavior, the variable can't be modified.

Logs
[✓] Flutter (Channel stable, 2.10.3, on Microsoft Windows [Version 10.0.22000.556], locale de-DE)
    • Flutter version 2.10.3 at X:\Flutter
    • Upstream repository https://github.com/flutter/flutter.git
    • Framework revision 7e9793dee1 (2 weeks ago), 2022-03-02 11:23:12 -0600
    • Engine revision bd539267b4
    • Dart version 2.16.1
    • DevTools version 2.9.2

[✓] Android toolchain - develop for Android devices (Android SDK version 31.0.0)
    • Android SDK at X:\SDK
    • Platform android-31, build-tools 31.0.0
    • Java binary at: X:\JetBrains\apps\AndroidStudio\ch-0\211.7628.21.2111.8193401\jre\bin\java
    • Java version OpenJDK Runtime Environment (build 11.0.11+9-b60-7590822)
    • All Android licenses accepted.

Activity

  1. changed the title [-]Dart-Defines can not be set by gradle build[/-] [+][Document] Usage of Dart-Define variables in gradle scripts[/+] on Mar 17, 2022
  2. added
    toolAffects the "flutter" command-line tool. See also t: labels.
    t: gradle"flutter build" and "flutter run" on Android
    and removed
    in triagePresently being triaged by the triage team
    on Mar 17, 2022
  3. Sese-Schneider commented on Mar 17, 2022

    @Sese-Schneider
    ContributorAuthor

    @maheshmnj thank you for your triage! as per your investigation it looks like you think its already implemented, and just not documented.
    Could you share the way to include the dart-define in gradle with us?

  4. maheshj01 commented on Mar 17, 2022

    @maheshj01
    Member

    Could you share the way to include the dart-define in gradle with us?

    @Sese-Schneider, I am not sure about it, nor I could find a way to use the dart define constants in Gradle scripts, Lets wait for the secondary triage to take a look at it, They may have a better understanding of it.

    cc: @blasten

  5. onkarmonks commented on Mar 18, 2022

    @onkarmonks

    @Sese-Schneider Did you find a way to do it?
    I need to send data on basis of my Android grade flavor to main.dart to set appropriate .env file

  6. Sese-Schneider commented on Mar 20, 2022

    @Sese-Schneider
    ContributorAuthor

    @onkarmonks we also had this issue in the past, but failed to find a way to do this.
    What we do is to supply --flavor and a --dart-define in the flutter build step.

    However, this question is about injecting the --dart-define in Androids gradlew assembleDebug step.

  7. roblframpton commented on Mar 23, 2022

    @roblframpton

    I found a solution to this. I inspected the verbose output of flutter build and found that the --dart-define flags get base64 encoded, comma-separated, and passed to a Gradle via a flag called -Pdart-defines. (Note the s at the end of this flag, since it contains all the defines).

    So for example, the following dart defines passed to Flutter:

    --dart-define myvar=123 --dart-define anothervar=test
    

    turn into the following flag passed to Gradle:

    -Pdart-defines bXl2YXI9MTIz,YW5vdGhlcnZhcj10ZXN0
    

    since, myvar=123 is bXl2YXI9MTIz in base64 and anothervar=test is YW5vdGhlcnZhcj10ZXN0 in base64. Simply pass this flag to your Gradle command, e.g.:

    gradlew -Pdart-defines bXl2YXI9MTIz,YW5vdGhlcnZhcj10ZXN0 assembleDebug 
    

    This solved the problem for me.

  8. Sese-Schneider commented on Mar 29, 2022

    @Sese-Schneider
    ContributorAuthor

    @roblframpton thank you very much, this solved our issues 🚀
    /cc @onkarmonks

    @maheshmnj given this is documented nowhere, I think the labels are correct as of missing documentation 👍🏼

  9. dustin-graham commented on Apr 6, 2022

    @dustin-graham

    For anyone else struggling to make the solution provided by @roblframpton , remember to base64 encode just the key=value portion of the --dart-define. This is probably obvious to everyone else but me, but I was encoding "--dart-define=key=value". That definitely does not work! @roblframpton explained it perfectly, just encode the key=value.

  10. ivan-horchakov commented on Apr 29, 2022

    @ivan-horchakov

    @roblframpton & @dustin-graham guys, inside my integration tests I have TEST_ENV var with the default value "develop". When I want to change it to "stage" for the local run via flutter driver - I'm using this:
    flutter drive --driver=test_driver/integration_test.dart --target=integration_test/tests/messaging_test.dart --dart-define=TEST_ENV=staging and it is working.
    But I need to figure out how to pass it during my Jenkins job, which builds and initiates test run in Firebase Test Lab. Here is my steps:

    1. flutter build apk --debug
    2. ./gradlew app:assembleAndroidTest
    3. ./gradlew app:assembleDebug -Ptarget="pwd"/../integration_test/smoke_test.dart
      I tried the approach, mentioned by you in points 2 & 3 (base64 & usual) but it still uses the default value "develop". TIA!
  11. krishnakumarcn commented on Apr 29, 2022

    @krishnakumarcn

    Hey @ivan-horchakov , I had a similar use case and solved it like this:

    ./gradlew assembleDebug --info -Ptarget=`pwd`/../integration_test/app_test.dart -Pdart-defines="{base64String}"
    

    Where {base64String} is the encoded key=value pair, in your case base64("TEST_ENV=staging")

    or directly from your previous code sample:

    ./gradlew assembleDebug --info -Ptarget=`pwd`/../integration_test/smoke_test.dart -Pdart-defines="VEVTVF9FTlY9c3RhZ2luZw=="
    
  12. ivan-horchakov commented on Apr 29, 2022

    @ivan-horchakov

    Thanks, @krishnakumarcn - you've made my day!

  13. added
    P3Issues that are less important to the Flutter project
    on May 31, 2022
  14. bartekpacia commented on Dec 3, 2022

    @bartekpacia
    Member

    I'm having a problem with passing dart defines to the app:connectedDebugAndroidTest task, which is needed to run integration tests natively on Android.

    ./gradlew app:connectedDevDebugAndroidTest \
      -Ptarget=$(pwd)/../integration_test/hsv_test.dart \
      -Pdart-defines="Q1RTX0RJU0FCTEVfTUFQX1BSRUxPQURJTkc9dHJ1ZQo=" 
    

    but it's spitting out really ugly error message:

    error message
    > Task :app:compileFlutterBuildDevDebug
    -DCTS_DISABLE_MAP_PRELOADING=true%0A: Error: Error when reading '-DCTS_DISABLE_MAP_PRELOADING=true%0A': No such file or directory
    
    
    > Task :app:compileFlutterBuildDevDebug FAILED
    
    FAILURE: Build completed with 2 failures.
    
    1: Task failed with an exception.
    -----------
    * Where:
    Script '/Users/bartek/fvm/versions/stable/packages/flutter_tools/gradle/flutter.gradle' line: 1159
    
    * What went wrong:
    Execution failed for task ':app:compileFlutterBuildDevDebug'.
    > Process 'command '/Users/bartek/fvm/versions/stable/bin/flutter'' finished with non-zero exit value 1
    
    * Try:
    > Run with --stacktrace option to get the stack trace.
    > Run with --info or --debug option to get more log output.
    > Run with --scan to get full insights.
    ==============================================================================
    
    2: Task failed with an exception.
    -----------
    * What went wrong:
    java.lang.StackOverflowError (no error message)
    
    * Try:
    > Run with --stacktrace option to get the stack trace.
    > Run with --info or --debug option to get more log output.
    > Run with --scan to get full insights.
    ==============================================================================
    
    * Get more help at https://help.gradle.org
    
    Deprecated Gradle features were used in this build, making it incompatible with Gradle 8.0.
    
    You can use '--warning-mode all' to show the individual deprecation warnings and determine if they come from your own scripts or plugins.
    
    See https://docs.gradle.org/7.5.1/userguide/command_line_interface.html#sec:command_line_warnings
    
    BUILD FAILED in 7s
    1 actionable task: 1 executed
    

    Update 1

    Hahah, it was my stupid mistake. I used echo, which adds a newline by default to the output.

    Bad:

    $ echo 'CTS_DISABLE_MAP_PRELOADING=true' | base64

    Good:

    $ printf 'CTS_DISABLE_MAP_PRELOADING=true' | base64

    Update 2

    The above works for app:assemble* family of tasks, but I have no luck with app:connectedDebugAndroidTest task :(

    > Task :app:compileFlutterBuildDevDebug FAILED
    Error parsing assemble command: your generated configuration may be out of date. Try re-running 'flutter build ios' or the appropriate build command.
    

    It works as if only a single dart-define is accepted.

  15. github-actions commented on Apr 6, 2023

    @github-actions

    This thread has been automatically locked since there has not been any recent activity after it was closed. If you are still experiencing a similar issue, please open a new bug, including the output of flutter doctor -v and a minimal reproduction of the issue.

  16. locked as resolved and limited conversation to collaborators on Apr 6, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    P3Issues that are less important to the Flutter projectdependency: dartDart team may need to help ust: gradle"flutter build" and "flutter run" on AndroidtoolAffects the "flutter" command-line tool. See also t: labels.

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions