Skip to content

Fix in Flutter Tools: Added kebab/param-cased as fileNames expected by the tool for multidimesional flavors in aab's build process - #124797

Closed
peupompeu wants to merge 6 commits into
flutter:masterfrom
peupompeu:fix-flutter-tools-for-multidimentional-flavor
Closed

peupompeu wants to merge 6 commits into
flutter:masterfrom
peupompeu:fix-flutter-tools-for-multidimentional-flavor

Conversation

@peupompeu

Copy link
Copy Markdown

This PR adds the kebab/param-cased version of the .aab bundle file name to the possible options so the gradle tool can look for it in the bundle directory and prevent the flutter build command failing because it could not find the .aab file and the end of the build.

List which issues are fixed by this PR. You must list at least one issue.
Fixes #65264

Based on @PritamSangani solution

Pre-launch Checklist

  • I read the Contributor Guide and followed the process outlined there for submitting PRs.
  • I read the Tree Hygiene wiki page, which explains my responsibilities.
  • I read and followed the Flutter Style Guide, including Features we expect every widget to implement.
  • I signed the CLA.
  • I listed at least one issue that this PR fixes in the description above.
  • I updated/added relevant documentation (doc comments with ///).
  • I added new tests to check the change I am making, or this PR is test-exempt.
  • All existing and new tests are passing.

If you need help, consider asking for advice on the #hackers-new channel on Discord.

@flutter-dashboard flutter-dashboard Bot added the tool Affects the "flutter" command-line tool. See also t: labels. label Apr 13, 2023
Comment thread .vscode/settings.json Outdated
@@ -6,6 +6,10 @@
// reformatting of code.
"editor.formatOnSave": false,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need these lines then?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nvm, we probably don't want to be autoformatting anything in this repo

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Vs-code doesn't respect the default rules of current .settings for the workspace scope, if you have especified some different behavior for ["dart"] in your global setup scope.

Added this lines to ensure respect for the original rules, avoiding auto formatting.

@christopherfujino

Copy link
Copy Markdown
Contributor

@gnprice do you know if this is a reasonable solution?

@gnprice

gnprice commented Apr 19, 2023

Copy link
Copy Markdown
Member

This certainly looks plausible as the sort of thing I'd expect AGP to do when picking this filename.

The last time I looked for documentation of this sort of thing, there really wasn't any at all. So unless that's changed, the only way to try to pin down AGP's behavior here is for someone to try things out — make a small example Android project, muck with the flavors in the build, and see what happens.

That or study the AGP implementation, I guess, but the empirical approach may be easier.

One case I'd be curious about is what happens when an individual flavor is more than one word long — e.g. there's a fooBar flavor combined with a bazQuux flavor, on two different dimensions. This code predicts, IIUC, that that would come out as a file like …/bundle/fooBarBazQuuxRelease/app-foo-bar-baz-quux-release.aab. Is that what AGP in fact picks?

Or for more of an exotic edge case: what happens when individual flavors have names that start with a capital letter, and/or contain an underscore? It looks like there's a test case for that just above the one this PR adds, with a single Foo_Bar flavor. I think that's not a conventional way to name these, though, so if correctly supporting those would be more work, then they don't matter as much as names like fooBar.

@peupompeu

peupompeu commented Apr 25, 2023 •

Copy link
Copy Markdown
Author

@gnprice

I'm interested in learning more about how the AGP behaves in different scenarios when it comes to naming files for projects with flavors. I'm willing to try out different use cases and experiment with various configurations. I'm going to try out the specific use case you mentioned with the fooBar and bazQuux flavors on two or more different dimensions to see what output file names are generated. I'll also look into the edge case you mentioned with flavors that have names starting with capital letters or containing underscores. Once I have some results to share, I'll provide a follow-up with my findings. Thanks again for your help!

@peupompeu

peupompeu commented Apr 25, 2023 •

Copy link
Copy Markdown
Author

Tested my proposal for this use cases:

    productFlavors {
        one {
            dimension "one"
        }
        two {
            dimension "two"
        }
        three {
            dimension "three"
        }
    }
    productFlavors {
        dimensionOne {
            dimension "one"
        }
        dimensionTwo {
            dimension "two"
        }
        dimensionThree {
            dimension "three"
        }
    }
    productFlavors {
        dimension_one {
            dimension "one"
        }
        dimension_two {
            dimension "two"
        }
        dimension_three {
            dimension "three"
        }
    }

In the current master the AGP exports the folders and files as follows:

camelCase file name:
app-one-two-three-release.aab
app-dimensionOne-dimensionTwo-dimensionThree-release.aab (fooBar example)

snake_case file name:
app-dimension_one-dimension_two-dimension_three-release.aab

In the latest master we get this error for the three file names:

Gradle build failed to produce an .aab file. It's likely
that this file was generated under
/home/pedro/Desktop/flutter_lab/build, but the tool
couldn't find it.

With my proposal we got a pass for the lowercase and snake_case flavor.
But still receives the error for camelCased flavor names ( fooBar example ).

As the flavor received from the BuildInfo class is only a string, we cant separate the dimensions of the flavor in fooBar situations
ex: --flavor dimensionOneDimensionTwoDimensionThree, cant distinct the dimensions separators in findBundleFile function

I would like to propose the addition of a restriction to flavor naming in flutter to only lowercase and snakeCase until we develop a better way to interpret the --flavor tag in the build command

@gnprice what do you think we should do next?

@andrewkolos

Copy link
Copy Markdown
Contributor

Thanks for the PR! Forgive me if I am misunderstanding, but I don't see how this fixes #65264. The issue (and the title of this PR) are about computing the correct .aab filename when building appbundles with multidimensional flavors, but the description and code change of this PR seems to be about an issue that occurs when the project has flavors with camelCased names (nothing to do with multidimensional flavors). This separate issue was mentioned as a comment on #65264, but I personally could not reproduce it on master on neither my MacBook nor my Ubuntu VM.

Regardless, we need a way to separate out each of the flavors per dimension (as @pepompeu pointed out). Here's one possibility I can think of: modify packages/flutter_tools/gradle/src/main/groovy/flutter.groovy to add a new task to print productFlavors. Then, modify packages/flutter_tools/lib/src/android/gradle.dart to invoke the task added in step 1 and read the output to get the separate flavors.

For inspiration, you can look at some code that does something similar for getting the build variants:

@peupompeu peupompeu changed the title Fix in Flutter Tools for multidimesional flavor Fix in Flutter Tools: Added kebab/param-cased as fileNames expected by the tool for multidimesional flavors in aab's Apr 28, 2023
@peupompeu peupompeu changed the title Fix in Flutter Tools: Added kebab/param-cased as fileNames expected by the tool for multidimesional flavors in aab's Fix in Flutter Tools: Added kebab/param-cased as fileNames expected by the tool for multidimesional flavors in aab's build process Apr 28, 2023
@peupompeu

Copy link
Copy Markdown
Author

Sorry for my confusion @andrewkolos, it's my first PR ever! Trying my best to help.

From my testing, the aab is built correctly and is placed in the output folder with the correct naming, in the correct place.

From my understanding, the problem is that the tool emits the warning reported in the issue if it can't find the outputed file.

The initial idea of the pr was to extend the files searched for the tool inside the folder to include this kind of outputs:

app-one-two-three-release.aab
app-dimensionOne-dimensionTwo-dimensionThree-release.aab (fooBar example)
app-dimension_one-dimension_two-dimension_three-release.aab

I'm missing something here?

@andrewkolos

Copy link
Copy Markdown
Contributor

From my testing, the aab is built correctly and is placed in the output folder with the correct naming, in the correct place.

From my understanding, the problem is that the tool emits the warning reported in the issue if it can't find the outputed file.

That's what I understand too. I think our difference in understanding is the problem that #65264 is describing. Focusing on only the issue description (first comment), I came up with this way to reproduce this issue:

  1. Create a new flutter project.
  2. In the android object android/app/build.gradle, add the following flavors:
flavorDimensions "signed", "env"

productFlavors {
    signed {
        dimension "signed"
    }

    unsigned {
        dimension "signed"
    }

    prodThing { // We include some camel-casing to make sure this is not an issue.
        dimension "env"
    }

    internalThing {
        dimension "env"
    }
}
  1. Run flutter build appbundle --flavor signedprodThing
  2. You should see the error about the tool not being able to find the .aab.

Adding a print statement to the tool code, I see this is where the tool looks:

build/app/outputs/bundle/release/app.aab
build/app/outputs/bundle/release/app-release.aab
build/app/outputs/bundle/signedprodthingRelease/app.aab
build/app/outputs/bundle/signedprodthingRelease/app-signedprodthing-release.aab
build/app/outputs/bundle/signedprodThingRelease/app-signedprodThing-release.aab

However, the file that actually exists is

build/app/outputs/bundle/signedProdThingRelease/app-signed-prodThing-release.aab
\\                                                        ^ Notice the hyphen used to separate the flavors by dimension.

This PR would add the following path to search:

build/app/outputs/bundle/signedprodThingRelease/app-signedprod-thing-release.aab

which is still different.

@gnprice

gnprice commented Apr 29, 2023

Copy link
Copy Markdown
Member

It seems like a sticky point here is that in a project like @andrewkolos's helpful example above,

  • AGP gives that example "build variant" a name like signedProdThingRelease, with the two flavors (from the two flavor dimensions) and the build type (i.e., debug vs. release) all joined together in camel case. Docs here: https://developer.android.com/build/build-variants#flavor-dimensions
  • If we have --flavor take a string like signedProdThing, then we can't tell whether that refers to (a) one flavor signedProdThing, (b) two flavors signedProd and thing, or (c) two flavors signed and prodThing. (In the example, the right answer is (c).)
  • But we need to know the difference, because AGP also joins together the names in a different way, with hyphens. And we need both versions signedProdThingRelease and signed-prodThing-release as part of the output filename

One solution to that would be, as mentioned, to add a Gradle task that tells us what the flavors and flavor dimensions are, so that we can unpack a string like signedProdThing. That has a downside, though: running even a trivial Gradle task is expensive. For example in examples/hello_world/, if everything's already warm, running cd android && ./gradlew help takes 2-3 seconds on my Mac.

(This might be improved in the future by fixing #119196; not sure how much.)

Here's another possible solution: we could say that when you have multiple flavor dimensions, you need to express the different flavors to --flavor in some unambiguous form. E.g. we could say the flavors should be comma-separated:

flutter build appbundle --flavor signed,prodThing

Then there'd be no question that there are two flavors, namely signed and prodThing. From that we could compute both of the different ways of joining those names — signedProdThing and signed-prodThing — in order to successfully compute the filename build/app/outputs/bundle/signedProdThingRelease/app-signed-prodThing-release.aab.

Conveniently that would also have zero impact on everyone who's using --flavor for a single flavor dimension today: they'd keep saying --flavor prodThing or whatever, and it would unambiguously mean that there's one flavor prodThing.

@gnprice

gnprice commented Apr 29, 2023

Copy link
Copy Markdown
Member

(I should also acknowledge, since I was somewhat negative above at #124797 (comment) about Android's level of documentation of this sort of thing in AGP, that the docs have improved! That page https://developer.android.com/build/build-variants#flavor-dimensions is quite helpful, and even spells out most of what the filenames look like. I don't think that was there a year or two ago; and in fact the Internet Archive first spotted that page just last week… indeed just a couple of hours after my comment.

Also although that page gives a very helpful example, it doesn't quite pin down the behavior to the degree one wants when writing code like this to interoperate with it. So the empirical investigations above are still essential.)

@christopherfujino

Copy link
Copy Markdown
Contributor

@pepompeu thanks for your willingness to contribute! However, it seems like the approach in this PR is not the solution we want for #65264. I think further discussion on the correct approach should happen on that issue.

@peupompeu
peupompeu deleted the fix-flutter-tools-for-multidimentional-flavor branch May 5, 2023 00:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

tool Affects the "flutter" command-line tool. See also t: labels.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

when building app bundle with multiple flavorDimension, tool cannot locate .aab file

4 participants