[eas-cli] Fix flavor detection when build.gradle uses string interpolation - #4260
Open
giaBaoJS wants to merge 2 commits into
Open
[eas-cli] Fix flavor detection when build.gradle uses string interpolation#4260giaBaoJS wants to merge 2 commits into
giaBaoJS wants to merge 2 commits into
Conversation
|
Subscribed to pull request
Generated by CodeMention Warning: The preamble and epilogue options in commentConfiguration are deprecated. Use template instead. |
…ation
gradle-to-js counts braces without knowing about string literals, so the
braces of a Groovy interpolation containing a method call, such as
buildConfigField "String", "KEY", "\"${System.getenv("KEY")}\"", make it
swallow the closing brace of the surrounding block. flavorDimensions and
productFlavors then end up nested inside android.defaultConfig, and
parseGradleCommand fails with "flavor staging is not defined".
Unwrap string interpolations before parsing, keeping their content and
dropping only the braces that confuse the parser.
giaBaoJS
force-pushed
the
fix-gradle-string-interpolation-parsing
branch
from
August 25, 2026 02:03
8a2bea9 to
3f650d2
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why
Fixes #2815.
In a bare project,
android/app/build.gradlelines like this one make EAS CLI stop seeing product flavors:flavorDimensionsandproductFlavorsend up nested insideandroid.defaultConfiginstead of onandroid, soparseGradleCommandreadsbuildGradle.android.productFlavorsasundefinedand throwsflavor staging is not defined. The user sees:The reporter found the workaround of switching to the parenthesised call form, but a normal space-separated Gradle call should work.
How
gradle-to-jscounts{and}without knowing about string literals, so the braces of a Groovy interpolation are treated as a block. Concretely, ingradle-to-js@2.0.1:deepParsesees the{of${...}and recurses into it as if it were a closure.parsingKeyistrue, so the(of the method call sends it intoskipFunctionCall.skipFunctionCalldoesstate.index++before it breaks, thendeepParsecontinues and theforloop incrementsstate.indexagain. One character past the closing)is swallowed, and in${System.getenv("KEY")}that character is the closing}.The recursion therefore never ends where it should and eats the closing brace of
defaultConfiginstead. Everything after that line stays nested one level too deep.I narrowed the trigger down to braces that contain parentheses.
"${abc}"parses fine today;"${a()}"is enough to break it. It is not specific tobuildConfigField,resValuebreaks identically.The fix preprocesses the file before handing it to
gradle-to-js, in the same spirit as the existing comment-stripping right above it (and as #2435, which added the same kind of workaround for empty single-line comments). Interpolations are unwrapped: the braces go, the content stays.Notes on the rule:
[^{}]*cannot match across a brace, so a Groovy closure inside an interpolation, like"${list.collect{ it }.join()}", is left alone. That case already parses correctly today and still does.gflag.$with no braces,$in a plain string, and top-level closures such asdoLast { ... }are never matched, since the pattern requires the literal${.${has no meaning in Groovy other than interpolation, so this does not touch anything else.Test Plan
New test
parsing build.gradle with interpolated stringswith fixturestring-interpolation-in-build.gradle, modelled on the build.gradle in the issue. It covers the reported line, two interpolations on one line,resValue, and an interpolation followed by a real closure (debugImplementation("...:${FLIPPER_VERSION}") { exclude ... }).Passing on this branch:
Reverting only the change in
gradleUtils.tsand keeping the test and fixture makes it fail for the right reason, with both keys missing fromandroid:For the same fixture, the parse result before and after the fix:
android.flavorDimensionsundefined"env"android.productFlavorsundefined{ staging, production }android.defaultConfigkeysapplicationId, minSdkVersion, targetSdkVersion, versionCode, versionName, buildConfigField(withresValue,flavorDimensions,productFlavors,buildTypesanddependenciesmisnested insidebuildConfigField)applicationId, minSdkVersion, targetSdkVersion, versionCode, versionName, buildConfigField, resValueNo behaviour change on anything that parses today. All five pre-existing fixtures produce byte-identical JSON before and after, and the preprocessing does rewrite text in every one of them (they all contain
${FLIPPER_VERSION}), so the comparison is not vacuous:I also drove
gradle-to-js@2.0.1directly over a matrix of Groovy constructs. Everything that parsed correctly before still does, and these now parse correctly too:${System.getenv("K")},${a()},${a}-${b}with calls,resValuewith an interpolation, single-quoted interpolations, an interpolation inside a closure, and nested interpolations such as${a("${b()}")}. Untouched and still correct:doLast { ... },applicationVariants.all { variant -> ... },"1.0-$suffix","$9.99",manifestPlaceholders = [...], and"${list.collect{ it }.join()}".Whole
eas-clipackage suite:2439 passed, with the only 2 failing suites (src/observe/__tests__/formatEvents.test.tsandformatCustomEvents.test.ts) failing identically on a cleanmainon my machine. They are date-locale snapshots (Jan 1, 2025vs1 Jan 2025), unrelated to this change.yarn typecheck,yarn lint(0 warnings, 0 errors) andyarn fmt:checkall pass.