There has been some discussion lately about how we might be able to allow for custom configurations in GradleFx. Such a custom configuration would allow a user to:
- generate different outputs from a single code base
- use specific dependencies for each of these outputs
- hook up any other custom task to a particular configuration
As these discussions illustrate it is not currently possible to do so. And though we are looking into some possible solutions, they may not be implemented soon. So here I am to save the day and provide you with a viable workaround, until we get the matter sorted out.
Use case
This solution is heavily based on mrhaki’s excellent article, but it is tailored specifically for the Flex developer that needs to generate multiple outputs for different environments from a single project. I created this when facing a real-world issue and the solution is being used in production right now, so it’s been tried and tested.
The specific situation I was facing was that I needed mock services and embedded mock data, in such a way that the application could run in standalone mode (i.e. without a server) and give a realistic feel to the users testing the UI. Of course in the production build I did not want to include all the additional classes and certainly not the embedded data. So here’s how I created a “clean” production output and a heavyweight development output including the mocks.
A groovy configuration
Let’s start by stubbing out our config file for two different environments.
1 2 3 4 5 6 7 8 9 10 11 |
|
Good, that’s how mrhaki described it. Now lets add some properties that we can use in a GradleFx build. Note that I put
all the mock-related code and the resources (the data files) in a separate source tree (src/mock/
), which allows me
to easily add/remove that part when needed.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
|
Note that in production
I mirrored every property that I declared in the dev
block, if only to set its value to an
empty array. This is not strictly nesessary, but it will make the code in the build file a lot more readable later on.
Use it in a build script
So we’ve configured our two environments. Next I will show you how to modify the Gradle(Fx) build script to leverage it.
As in mrhaki’s post, this script reads the custom env
property from the issued command and processes the config file
accordingly. Hence you’ll be able to initiate the build of a specific build like so:
1
|
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
|
See why we declared empty arrays in the production
block? It would’ve required some conditional logic if we hadn’t,
leaving the result much less elegant and readable. Especially the merged
dependency would’ve been butt-ugly; believe
me, I tried.
Conclusion
Well that’s about it. It’s not extremely complicated and it’s fairly elegant. I know it’s not exactly the Gradle way, but it gets the job done without too many compromises. Hope this helps someone.