After not the most successful, in my opinion, experiment on building flex using maven (
details here ), I decided to try gradle, about which they write that he took the best from ant and maven and this is the next development step. I decided to conduct an experiment according to this 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 out of this, please under the cut, because there is a lot of text. It was written directly in the course of the experiment, if you read completely lazy, then at the end there is a link to the test project.
Installing Gradle and First Impressions.
Razipuy - copy + Gradle_Home / bin into a common Path. Absolutely. A nice hint in the command line, even with color.
Gradle base helpD:\Projects\GradleFlexTest>gradle tasks :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. BUILD SUCCESSFUL
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 quite enough to realize the basic principles of the system.
The command line has user friendly gui for console
gradle --gui
:
gradle --gui
Notes- When using the command line, in the startup folder, gradle creates its own temporary folder .gradle, where it adds temporary work artifacts. The folder is not large, but after the experiments it would be better to delete or ignore it in the gita.
- When you start gui, an additional settings file is created in the startup folder. I think to act by analogy with the first.
- When trying a test build of an empty folder, a build file of build.gradle is created with default settings. Trifle, but nice.
Flex project
Flex is not yet included in the main documentation and there are no examples on it in the delivery. This seems to be understandable, although, of course, it is a pity, because there are quite a lot of other examples. But, a quick overview of the plug-ins pleased with the presence of a recognized plug-in for flex - GradleF. Let's start with it.
GradleFX
At first glance, the project is well documented, although only a bold experiment will show how exactly.
The first joy : the plugin is in the central maven repository. From there I recognize his latest version of it and will try.
The second joy : there is more than one option to indicate with which FlexSDK the project will work. There is a standard FLEX_HOME, a direct indication of the path on the local disk and dependencies. The last way I like the most, as the most versatile.
So, I define the project type as swf, I take the Apach Flex SDK dependency (because I haven’t tried it before) and I define the path to the zipu auto flex flex sdk (a great feature, given the lack of flex sdk in the repositories).
')
First startSince there is nothing besides build.gradle, I got fail on the output, but this is expected. What happened on the basis of the log (I do not post the log itself, it is painfully large)?
- A folder called .gradle has appeared in the home directory, which is the local repository of artifacts. Here, most likely, everything that will be downloaded will be added.
- The GradleFX plugin was loaded from the central maven repository and located on .gradle \ caches \ artifacts-24 \ filestore \ org.gradlefx \ gradlefx \ 0.6.4 \ (apparently, all downloads fall into .gradle \ caches \ artifacts-24 \ filestore \ I didn’t find any more places)
- Booted and unpacked ahache flex sdk
- The swf-object, swfobject-fabridge, osmf was loaded, asked about the license for osmf, blase-ds, adobe flex sdk
It was loaded, a little more than I expected, for example, adobe flex sdk is not very clear to me, perhaps this is a dependency of something. I was asked twice if I agree to upload something, maybe my legs grow from there. But nevertheless, it can be considered luck, because the required components are found.
Scaffold and first build.
Scaffold plugin - model project generation. By and large, this is a one-time action, but why not try, since it is still there. At present, the scaffold has only one task - to create a sample project.
gradle scaffold
As expected, a folder structure has been created and the main.mxml file is a stub. I try to make the first build of what happened.
The first feature Very long handling of the Air SDK, when calling any task, even
gradle tasks
, it is released, and this is clearly unnecessary. Perhaps this is my mistake, I included both dependencies on flex and air. I try to remove the air, as not much needed right now. It turns out that I didn’t read the documentation very carefully, it’s right there that unpacking sdk depends on the type of result, but it happens in the same folder. This may mean that when working alternately with different types of projects (air / flex), the necessary sdk will be released. If the type of the project has not changed, then it should not happen again.
So, the first build failed, the second was completed successfully. What was it? Having two dependencies, one of which excludes
the second got:
- auto installation flex sdk
- auto installation of air sdk (it was from here that a long run was taken)
- actual main.mxml build using the latest (air) sdk installed
- result - fail - the configuration file was not found, which is quite logical.
I remove the air dependence and try to collect again. Collected. I get the build folder, which contains the flash and its related components. The second release did not happen, everything is in order.
Notes- Gralde constantly displays warnings to the plug-in developer: some methods are marked as deprecated , they will be removed in version 2 (current 1.6), use others instead. I have always been pleased with such messages. The warning is much nicer than removing methods immediately. In addition, a new path is immediately indicated. A clear plus for gradle developers.
- This experiment fully 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.
Comparing build time (sec.)build | gradle | maven | idea |
---|
one | 12.031 | 12.172 | 13 |
2 | 6.25 | 7.63 | four |
I also wanted to compare with FlashDevelop, but it does not display build time. The IDEA win is most likely based on a one-time configuration download, on the first build of the project.
As3 compile
I try to translate the project pure as3. You can still disable scaffold, but it does not seem to interfere, although it is no longer needed. The presence of this plugin does not affect the speed of assembly, perhaps a little more memory takes. So, changing Main.mxml to Main.as. Build does not pass. Quite honestly says that Main.mxml is not found. I look at the documentation and find the property that is responsible for the entry point. This is the
mainClass
. It is more logical to invent. Set a new value - build success! Stage pure as3 project passed.
Note For a pure as3 project, it makes sense to specify
frameworkLinkage='none'
, i.e. do not link flex to the fly (-200 b approximately).
Flex unit tests.
I add a stub class and a test that checks it. Like maven, you need to locate the debug FashPlayer. Again, you can use the system variable FLASH_PLAYER_EXE or set
flexUnit.command
directly. I use the latter method as more explicit (well, I don’t like to use system variables). Moreover, if desired, it can be put into properties and used similarly to maven profiles.
I add the required dependencies. A small gag, as usual, in the repository. FlexUnit does not support its repository and does not publish it in public, at least officially. The GradleFX documentation strongly recommends deploying your repository, but for now something is not very desirable.
Interestingly There is an interesting link to the
CI server, you can see how this project is going.
Caution The
documentation for a typo for flexunit-tasks is the extension 'jar', not 'swc'. In the example file dependency is written correctly.
FlexUnit in GradleXF works through Ant-flex flex-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, but GradleFX itself is. Some searches showed no flexUnitTasks-4.1.0-8.jar file in the public repositories. This again pushes to deploy its. 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 in `/`, and not in `\`, as everyone is accustomed to under Windows. This error will be politely indicated by the output of the command line, which will greatly shorten its search time. The command line pleases more and more, while the most informative of those that I have seen.
Comparison of test run time (sec.)build | gradle | maven | idea |
---|
one | 31.061 | 37.891 | 13 |
2 | 14.75 | 17.516 | 7 |
For IDEA, the exact time is difficult to say, it is not displayed in total. Counted on the log. First run: 10 build + 3 tests. True actual lead time is indicated as 1.56 s. But the log was completed 1.5 later. Second launch: 5 build + 2 tests. The actual time is again less than 1.5. But in any case, IDEA is still the leader in speed.
In fact, unit testing was successful. But there is one trouble - the build file became non-portable, i.e. addicted to absolute paths, plus a large enough preparation for the first run. I want to get rid of this drawback and add the ability to auto-update flexunit dependencies in the same way as flex sdk. Since I am not a groovy connoisseur (I don’t know at all), I’ll try to do it using the example of the flex sdk automatic installation. Rummaging through the examples and source codes of GradleFX, I collected a small add-on that downloads the 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 a standard setting via system variables is preserved.
The first launch lengthened (the very first) to 3 minutes (mainly due to downloading flexunit - a very slow process), but the second returned to the old 14 seconds.
Fla as a static resource
I'll make a small fla resource library and try to compile it in swc before compiling. As a continuation of hello from Adobe, jsfl scripts can not accept parameters from the command line. This means that the script will have to be partially generated. 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 longer it will be). For generation, I use the
fl.publishDocument
method, which, as it were, does not open fla, but publishes it in
silent mode. Rumor has it that it is faster and no memory flows. As usual, the first compilation is the slowest, then quickly enough. The question of what will happen if fla will be many, remains open.
Note Adobe ExtendScript Toolkit, Adobe's native editor for jsfl scripts, is close in convenience to the CS action editor, those. Made for strong spirit people. I tried and forgot like a bad dream.
I try to attach this script to an existing build. Somewhat bothered to write in a notebook, I try to import the project into IDEA and write there. The import went well, all tasks are visible and they are executed. 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, autocomplete would be very useful.
I try the second way, maybe the developers GradleFX have provided something more global for IDEA. For this I use the IDE plagin plugin.
Hidden text gradle idea :scaffold Creating directory structure src/main/actionscript src/main/resources src/test/actionscript src/test/resources Main class already exists src/main/actionscript/ :idea 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 is not implemented ... Well, okay, with such support for syntax and AkelPad does an excellent job.
General concepts of groovy still need to be explored (for typical projects, you can get by with examples from the documentation) if you want to make something of your own. By the way, there is a good article on Habré
Groovy in 15 minutes .
Surprises continue, fileUri is not universally understood in the same way, 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 of CS does not work, but does not fall. Just nothing happens. After some immersion in Google and console output, a task was assembled to build fla files into swc (with some restrictions). By and large, there is only one absolute way. This is CS. It is hardly a big problem, it is impossible to install it automatically, and the installation paths are less standard. I will consider this an agreement.
Notes- CS can be set in PATH, then cmd can directly execute jsfl scripts.
- I looked at ant examples on launch via the command line. It turns out you can get rid of the absolute path to CS.
task flaBuild << { ... }
tasks should be defined as task flaBuild << { ... }
in this case, the task is not launched for execution when the skpt is executed spontaneously. Defining a task as task flaBuild(){ ... }
or task flaBuild{ ... }
launches it for execution regardless of its call. Most likely, this is a groovy / gradle feature that I do not know.- CS "holds" the last jsfl or swc executable, so the
clean
task cannot delete the build folder. This can be corrected by adding an explicit CS closure, but this will greatly lengthen the assembly. So for now, leave it like this.
I add the build task to the flaBuild task and try to access the library resource, which is exported under the name “SymbolView”. Prada, I am somewhat confused by the sequence of tasks based on the log:
:copyresources :compileFlex UP-TO-DATE :flaBuild :copytestresources
This may mean that I made a dependency on the wrong task. Similarly, the compileFlex task should have a dependency, although it is not in the
gradle tasks
list. There should also be a dependency on the collected fla-resources. I used the feature that is in the java plugin. Found it by chance, looking at the list of available properties of the project. Perhaps this is not entirely fair, but since such a property exists, then why not.
So, the stage “fla as a static resource” can be considered as completed.
Reliase compress
To compress the final flash I will use the Apparat project I encountered when I was watching FlexMojos. For maven there is a standard plugin, which is even in the repository. I will try to use the part for ant.
Unfortunately, there is no documentation ant, 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. Perhaps later. It would be great here to take advantage of dependency resolution provided by the maven repository, but this is not quite a dependency of the project, but rather an analogue of the plugin. In other words, I do not really understand how to use it later.
Found
issue 47 , so this can be implemented more smoothly. Therefore, I miss.
FlexPMD
The second time I want to use this project and the second time I can’t do it in a simple way. The actual lack of documentation completely discourages trying. As a repository out exhibited
svn , who wants to, can rummage. Part of it is the maven repository in a very peculiar form. 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 suddenly it turned out, despite the peculiarity of the native documentation, it was possible to get a report on the existing code. True, I did it only for one source directory, but I don’t have more. In addition, it is not difficult to fix it.
I don’t really understand the state of this project, it’s kind of necessary, but it’s in a very neglected form, it’s like the developers took it and transferred it to other projects one day. And this is carried out exclusively in free time. Although for free, it's a sinful loaf to chop up.
Multi-modular project
The documentation for the plugin states that multi-module projects are typically done and refer to the gradle documentation. Well, then I will try it. I will divide the existing project into two: application and library.
Everything turned out to be quite simple. You can define 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.
Out of trouble: the project began to gather much longer, about 21 seconds, against 14, as it was before. Perhaps these are solutions for the integration server.
As a conclusion
Gralde is a very powerful build tool, for typical solutions the entry threshold is not large. To create something exotic, you need to know groovy, gradle api and the features of the plugins used. The resulting build script is generally understandable, even without the knowledge of groovy, is much more compact than xml.
GradleFX can do almost everything that is required for development. I just didn’t have enough ability to auto-install zips, but it turned out to be done on my knee. Perhaps this is already there, since there is a dependency of the type archive, you need the ability to unpack (or auto-install). It was not possible to try to resolve complex transitive dependencies, but they promise that it is.
In general, the sensations from the sample are good, much better than from maven + FlexMojos. It's good that there is a standard, but you can break it. This is especially true for flex / flash, because here 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 you can do groovy projects, and there it is most likely there.
The project on which the experiments were conducted , there is also a draft of the article, which was written in the course of the action. By diffs, you can see exactly what and when added.
Resources
GradleHabr about gradleMaven -> Gradle life examples, discussionGradleFXjsflApparat - framework to optmize ABC, SWC and SWF filesFlexPMD