Build a flex / as3 project using gradle

    After a not very successful experiment, in my opinion, to build flex using maven ( details are here ), I decided to try gradle, about which they write that he took the best from ant and maven and this is the next step in development. I decided to conduct an experiment according to such a plan:
    • flex compile (Path to FlexSDK / maven dependency)
    • as3 compile
    • flex unit run (dependency)
    • fla compile as static resource
    • reliase compress
    • code quality (FlexPMD)
    • multy module project

    Who cares what came of it, I ask for a cut, because there is a lot of text. It was written right in the course of the experiment, if you read completely laziness, then at the end there is a link to a test project.

    Gradle installation and first impressions.

    Unzip - copy + Gradle_Home / bin into the common Path. Absolutely nothing. Good hint on the command line, even with color.
    Gradle base help
     D:\Projects\GradleFlexTest>gradle tasks
    	All tasks runnable from root project
    	Build Setup tasks
    	setupBuild - Initializes a new Gradle build. [incubating]
    	Help tasks
    	dependencies - Displays all dependencies declared in root project 'GradleFlexTest'.
    	dependencyInsight - Displays the insight into a specific dependency in root project 'GradleFlexTest'.
    	help - Displays a help message
    	projects - Displays the sub-projects of root project 'GradleFlexTest'.
    	properties - Displays the properties of root project 'GradleFlexTest'.
    	tasks - Displays the tasks runnable from root project 'GradleFlexTest' (some of the displayed tasks may belong to subprojects).
    	To see all tasks and more detail, run with --all.

    For an initial understanding of how this all works, you can read the initial chapters of the user guide, up to about chapter 9. This is enough to realize the basic principles of the system.
    The command line has a user friendly gui for console lovers: gradle --gui
    • When using the command line, gradle creates a temporary .gradle folder in the startup folder, where he adds temporary work artifacts. The folder is not big, but after experiments it would be better to delete it or to ignite it in the gita.
    • When gui starts, an additional settings file is created in the launch folder. I think to act by analogy with the first.
    • When you try a test build of an empty folder, a build.gradle build file is created with the default settings. A trifle, but nice.

    Flex project

    Flex is not yet included in the main documentation and there are no examples of it in the delivery. This seems to be understandable, although, of course, a pity, because there are a lot of other examples. But, a quick look at the plugins pleased with the presence of a recognized plugin for flex - GradleF. We’ll start with him.


    At first glance, the project is well documented, although only a bold experiment will show how much.
    First joy : the plugin is in the central maven repository. From there I will learn his latest version of it and I will try.
    The second joy : there is more than one option to indicate which FlexSDK the project will work with. There is a standard FLEX_HOME direct path to the local drive and dependencies. The last way I like the most, as the most universal.

    So, I determine the type of the project as swf, take the dependency on the Apach Flex SDK (because I have not tried it before) and determine the path to the flex sdk auto-install zip (a great feature, given the lack of flex sdk in the repositories).

    First start
    Since there is nothing other than build.gradle, I got fail on the output, but this is expected. What happened even proceeding from the log (I can’t upload the log itself, it’s too big)?
    • The .gradle folder appeared in the home directory, which is a local repository of artifacts. Here, most likely, everything that will be downloaded will be added.
    • The GradleFX plugin was downloaded from the central maven repository and placed on .gradle \ caches \ artifacts-24 \ filestore \ org.gradlefx \ gradlefx \ 0.6.4 \ (apparently, all downloads go to .gradle \ caches \ artifacts-24 \ filestore \, like I didn’t find more places)
    • Ahache flex sdk loaded and unpacked
    • Swf-object, swfobject-fabridge, osmf loaded, asked about the license for osmf, blase-ds, adobe flex sdk

    It booted up, somewhat more than I expected, for example adobe flex sdk is not very clear to me, maybe this is a dependency of something. They asked me twice whether I agree to download something, maybe my legs grow from there. Nevertheless, this can be considered good luck, because the required components were found.

    Scaffold and the first build.

    Scaffold plugin - generation of a typical project. By and large, this is a one-time action, but why not try it, since it is still there. At the moment scaffold has only one task - to create a standard project.
    gradle scaffold

    As expected, the folder structure and main.mxml file are created as a stub. I'm trying to make the first build of what happened.

    The first feature A very long processing of the Air SDK, when you call any task, even gradle tasksit is unzipped, and this is clearly superfluous. Perhaps this is my mistake, I included both dependencies on flex and on air. I'm trying to remove air, which is not very necessary right now. It turns out that I didn’t read the documentation very carefully, it says explicitly that sdk unpacking depends on the type of result, but it happens in the same folder. This may mean that when working in turn with different types of projects (air / flex), the necessary sdk will be unzipped. If the type of project has not changed, then re-unzipping should not occur.

    So, the first build failed, the second ended successfully. What was it? Having two dependencies, one of which excludes the
    second received:
    • auto installation flex sdk
    • auto installation of air sdk (it was from here that a long razipovka was taken)
    • actual build main.mxml using the latest (air) installed sdk
    • result - fail - the configuration file was not found, which is logical enough.

    I remove the air-dependence and try to assemble again. Assembled. I get the build folder, in which the flash and its related components lie. The second razipovka did not happen, everything is in order.

    • Gralde constantly displays warnings that should go to the plugin developer: some methods are marked as deprecated , in version 2 (current 1.6) they will be deleted, use others instead. I have always been pleased with such messages. A warning is much nicer than immediately deleting methods. In addition, a new path is immediately indicated. A clear plus for gradle developers.
    • This experiment completely explains the extra jumps that surprised me in the log. If air sdk depends on adobe flex sdk, which is generally logical, then it additionally downloaded. As a conclusion, read carefully and sometimes think. This is useful.

    Comparison of assembly time (sec.)
    I also wanted to compare it with FlashDevelop, but it does not display the build time. The IDEA win is most likely based on a one-time configuration download, at the first build of the project.

    As3 compile

    I am trying to translate a clean as3 project. You can also disable scaffold, but it doesn’t seem to interfere, although it is no longer needed. The presence of this plug-in does not affect the build speed, it may take a little more memory. So, I am changing Main.mxml to Build does not pass. Quite honestly, Main.mxml was not found. I look at the documentation and find the property that is responsible for the entry point. That mainClass. It’s more logical to come up with. Set a new value - build success! The pure as3 project stage is over.

    Note For a pure as3 project, it makes sense to specify frameworkLinkage='none', i.e. Do not link flex to the flash (-200 b approximately).

    Flex unit tests.

    I add a stub class and a test that tests it. Like maven, you need to locate the FashPlayer. Again, you can use the FLASH_PLAYER_EXE system variable or set it flexUnit.commanddirectly. I use the latter method as a more explicit one (well, I don’t like to use system variables). Moreover, if desired, this can be put into properties and used similarly to maven profiles.
    Add the required dependencies. A small plug, as usual, in the repository. FlexUnit does not support its repository and does not upload it to public, at least officially. The GradleFX documentation strongly recommends deploying your repository, but for now, you don’t really want to.

    Interesting There is an interesting link to the CI serverYou can see how this project is going.

    Caution In the documentation, a typo of dependencies for flexunit-tasks is an extension of 'jar', not 'swc'. The file dependency example is spelled correctly.

    FlexUnit in GradleXF works through Ant's flexunit-tasks. This is not exactly the surprise that I would like to see, but on the other hand, why duplicate the functionality? The problem is that this file is not in the repositories, and GradleFX itself is. Some search revealed the absence of the flexUnitTasks-4.1.0-8.jar file in public repositories. This again pushes to deploy their own. But, to run unit tests, you need three dependencies: flexunit itself, flexunit-tasks (ant part), flexunit-cilistener for communication between them. Somehow a lot for a simple test. Therefore, I take the file dependency from the example.
    gradle test

    Completely successful completion.

    Note for Win users. All paths are defined through `/`, and not through `\`, as everyone is used to under Windows. The output of the command line will politely indicate this error, which is great to reduce the time of its search. The command line pleases more and more, while the most informative of those that I have seen.

    Comparison of test execution time (sec.)
    For IDEA, the exact time is difficult to say, in total it is not displayed. Counted by the log. First run: 10 build + 3 tests. True, the actual runtime is indicated as 1.56 s. But the log ended 1.5 later. Second run: 5 build + 2 tests. Actual time is again less than 1.5. But in any case, IDEA is still the leader in speed.

    In fact, we were able to use unit testing. But there is one trouble - the build file has become nonportable, i.e. dependent on absolute paths, plus a lot of preparation for the first run. I want to get rid of this drawback and add the ability to auto-install flexunit dependencies similarly to flex sdk. Since I am not a connoisseur of groovy (I don’t know at all), I will try to do this using the flex sdk autoinstallation example. Having rummaged through GradleFX examples and source codes, I put together a small add-on that downloads dependencies for unit testing if necessary. The code, of course, does not shine with grace, but, for the first time, probably not bad. At the same time, the possibility of standard settings through system variables was preserved.

    The first run lengthened (the very first one) to 3 minutes (mainly due to downloading flexunit - a very slow process), but the second one returned to the old 14 seconds.

    Fla as a static resource

    I will make a small fla resource library and try to build it in swc before compiling. As a continuation of greetings from Adobe, jsfl scripts cannot accept parameters from the command line. So you have to partially generate the script. In fact, the script will run in Flash CS, and whether you want it or not, it should be open (if not, it will still open, only it will last longer). For generation, I use a method fl.publishDocumentthat, as it were, does not open fla, but publishes it in quiet mode. Rumor has it that it is faster and memory does not flow. As usual, the first compilation is the slowest, then fast enough. The question of what will happen if fla is a lot remains open.

    The noteThe Adobe ExtendScript Toolkit, the native editor for jsfl scripts from Adobe, is close to the CS action editor, those. made for strong-willed people. I tried and forgot like a nightmare.

    I try to fasten this script to an existing build. I'm tired of writing in notebooks, I'm trying to import a project into IDEA and write there. Import went well, all tasks are visible and they are being implemented. But by default, after importing, writing buid.gradle is almost exactly the same as in notepad. I was hoping for more support. When you don’t know the language, an autocomplete would be very helpful.
    I’m trying the second way, maybe the GradleFX developers have envisioned something more global for IDEA. To do this, I use the IDE plagin plugin.
    Hidden text
    	gradle idea
    	Creating directory structure
    	Main class already exists
    	Verifying project properties c
    	Creating IntelliJ IDEA project
    	:idea FAILED
    	FAILURE: Build failed with an
    	* What went wrong:
    	Execution failed for task ':id
    	> TODO implement IdeaProject

    Oops, it turns out this task has not been implemented ... Well, okay, AkelPad copes with such syntax support.

    General concepts about groovy still have to learn (for standard projects, you can get by with examples from the documentation) if you want to do something different. By the way, there is a good article on Habré Groovy in 15 minutes .

    Surprises continue, fileUri is not universally understood, as it suddenly turned out.
    	Adobe jsfl fileUri file:///d|/Projects/GradleFlexTest/src/main/fla/
    	Groovy fileUri     file:/D:/Projects/GradleFlexTest/src/main/fla/

    With the second type, CS does not work, but it does not crash. Nothing just happens. After some immersion in Google and the output of the console, the task was assembled to build fla files in swc (with some limitations). By and large, there was one absolute path. This is CS. It is unlikely that this is a big problem, it is impossible to install it automatically, and the installation paths are more or less standard. I will consider this an agreement.

    • CS can be written in PATH, then cmd will be able to directly execute jsfl scripts.
    • Looked at examples of ant running through the command line. It turns out you can get rid of the absolute path to CS.
    • The tasks of the build must be determined, as task flaBuild << { ... }in this case the task is not launched for execution when the script is executed spontaneously. Defining a task as task flaBuild(){ ... }or task flaBuild{ ... }launches it for execution regardless of its call. This is most likely a groovy / gradle feature that I don't know.
    • CS "holds" the last executable jsfl or swc, so the task cleancannot delete the build folder. This can be fixed by adding an explicit CS closure, but this will greatly lengthen the build. Therefore, I’ll leave it like that for now.

    I add the build task’s dependency to the flaBuild task and try to access the library resource, which is exported under the name SymbolView. Prada, I'm somewhat confused by the sequence of tasks based on the log:
    	:compileFlex UP-TO-DATE

    This may mean that I made a dependency on the wrong task. Exactly, the compileFlex task should have a dependency, although it is not in the general list of tasks gradle tasks. There should also be a dependency on collected fla resources. I used the opportunity that is in the java plugin. I found it by chance, looking at the list of available properties of the project. Perhaps this is not entirely honest, but since there is such a property, then why not.
    So, we can consider the stage “fla, as a static resource”, passed.

    Reliase compress

    To compress the final flash, I will use the Apparat project, which I encountered when I watched FlexMojos. For maven there is a standard plugin that even exists in the repository. I will try to use the part for ant.
    Unfortunately, there is no ant documentation, but there is an example, and I will take it as a basis. Failure - apparat requires scala to work. I also do not want to install it either. Maybe later. It would be great here to take advantage of the dependency resolution provided by the maven repository, but this is not really a project dependency, it is rather an analogue of the plugin. In other words, I don’t really understand how to use it later.
    Found issue 47 , so it can be implemented more evenly. Therefore, I miss.


    The second time I want to use this project and the second time I can’t do it simply. The actual lack of documentation completely discourages trying. As a repository svn is exposed outside , who wants, can rummage. Part of it is a maven repository in a very peculiar way. There are zips that need to be downloaded and unpacked. Those. if I understand correctly, using this as a maven dependency will not work.
    But unexpectedly, despite the peculiarity of the native documentation, I managed to get a report on the existing code. True, I did it for only one source directory, but I have no more. Moreover, to fix this is not at all difficult.
    I don’t really understand the state of this project, it’s as if it’s needed, but it’s in a very neglected form, it seems that the developers were taken and transferred to other projects one day. And this is conducted exclusively in his spare time. Although the free sinful crumble loaf.

    Multi-modular project

    The documentation for the plugin says that multi-module projects are done typically and refer to the gradle documentation. Well, then I’ll try it. I will split the existing project into two: an application and a library.
    Everything turned out to be quite simple. You can determine the dependencies of projects among themselves in almost any way. All projects are available for each other. Build can be run for any project separately, or for all together.
    From troubles: the project began to gather much longer, about 21 seconds, against 14, as it was before. Perhaps these are solutions for the integration server.

    In conclusion

    Gralde is a very powerful build tool, for typical solutions the threshold for entering it is not large. To create something exotic, you need knowledge of groovy, gradle api and the features of the plugins used. The resulting build script is generally understandable, even without groovy knowledge, much more compact than xml.
    GradleFX can do almost everything that is required for development. I only lacked the ability to automatically install zips, but it turned out to be done on the knee. Perhaps this already exists, since there is a dependency of type archive, you need the ability to unpack (or auto-install). It was not possible to try the resolution of complex transitive dependencies, but they promise that it is.
    In general, the sensation from the sample is good, much better than from maven + FlexMojos. It’s good that there is a standard, but you can violate it. This is especially true for flex / flash, because here the standards somehow do not really take root.
    Support from IDEA is noticeably weaker than for maven. In fact, the basic functions of calling tasks are available, there is no support for writing the script itself. This is strange, because groovy projects can be done and there it most likely is.
    The project on which the experiments were conducted , there is also a draft article, which was written in the course of action. By the diffs, you can see what exactly and when was added.



    Habr about gradle

    Maven -> Gradle life examples, GradleFX discussion


    Apparat - framework to optmize ABC, SWC and SWF files


    Also popular now: