A beginner's question.
I'm building a .swf with Flex Ant.
To my .swf I link a file, target.as, which I generate from file source.txt with command
./tool.sh source.txt > target.as
How can I add what is described in the above sentence to my ant build process?
The exec task executes any external program:
<exec executable="${basedir}/tool.sh" dir="${basedir}" output="target.as">
<arg path="source.txt"/>
</exec>
So if you use the mxmlc ant task to compile your swf, you can define your build task like this:
<target name="build">
<exec executable="${basedir}/tool.sh" dir="${basedir}" output="target.as">
<arg path="source.txt"/>
</exec>
<mxmlc ....>
...
</mxmlc>
</target>
To run that command in Ant use the exec task.
<exec executable="tool.sh" dir="toolshdir" output="target.as">
<arg value="source.txt" />
</exec>
http://livedocs.adobe.com/flex/3/html/anttasks_1.html
You may also want to use the Flex "mxmlc" task instead of calling it with exec. You can do a lot of configuration right within the XML if you'd prefer not to have to maintain the shell script.
Related
Are there any good tutorials for integrating grunt with ant? Our current build uses ant because we are a Java shop. However, the front-end is beginning to become a first class citizen, and we are examining using node and grunt for the front-end build. I need to integrate the front-end build with the ant build. I need to know how to normalize the exit codes for all my custom tasks as well as the built in grunt tasks and limit the console output to these predefined codes when the grunt tasks are called by ant. Any help would be greatly appreciated.
You could use this macro:
<macrodef name="exec-node">
<attribute name="module" description="The name of the NodeJS module to execute"/>
<attribute name="failonerror" default="true" description="Fail if the exit code is not 0"/>
<element name="args" implicit="yes" description="Argument to pass to the exec task"/>
<sequential>
<exec executable="cmd.exe" failonerror="#{failonerror}" osfamily="winnt">
<arg line="/c #{module}" />
<args/>
<!-- Windows cmd output workaround: http://stackoverflow.com/a/10359327/227349 -->
<!-- Forces node's stderror and stdout to a temporary file -->
<arg line=" > _tempfile.out 2<&1"/>
<!-- If command exits with an error, then output the temporary file -->
<!-- to stdout delete the temporary file and finally exit with error level 1 -->
<!-- so that the apply task can catch the error if #failonerror="true" -->
<arg line=" || (type _tempfile.out & del _tempfile.out & exit /b 1)"/>
<!-- Otherwise, just type the temporary file and delete it-->
<arg line=" & type _tempfile.out & del _tempfile.out &"/>
</exec>
<exec executable="#{module}" failonerror="#{failonerror}" osfamily="unix">
<args/>
</exec>
</sequential>
</macrodef>
And you can call any command: example:
<target name="jshint">
<exec-node module="grunt">
<arg value="jshint" />
</exec-node>
</target>
works like a charm: also ensures the stderr is also printed, which is a common problem when calling grunt.
Grunt can call out to the command line, so you could easily create several tasks in grunt that do nothing but execute an ant task via the shell.
The grunt-shell library makes it especially easy to execute external commands from a grunt task: https://github.com/sindresorhus/grunt-shell
Since you're talking about custom exit codes, though, you'll probably have to end up writing your own custom grunt task that executes a shell command and then looks at the response code (perhaps using the grunt.helpers.spawn helper): https://github.com/gruntjs/grunt/blob/master/docs/api_utils.md#gruntutilsspawn
My advice? My organization recently went through the same thing and it's best if possible to just make a clean break from ant and get rid of it entirely for your JavaScript-related projects.
Grunt has such a growing and useful library of plugins I'd be surprised if you couldn't duplicate your ant build files and create a 100% javascript solution.
you might use http://abc.tools.qafoo.com/ which includes an npm module *1)
The only thing you then need is a custom Target like:
…
<target
name="-mm:compile:main~hooked"
extensionOf="-compile:main~hook"
depends="
-my-compile-npm-hook
"
>
<target
name="-my-compile-npm-hook"
>
<echo>install local grunt-cli</echo>
<antcall target="npm:install">
<param name="in.npm.package.name" value="grunt-cli" />
</antcall>
</target>
…
after that you might run grunt in the .npm/node_modules/.bin/ directory alias ${npm.local.modulesdir}/.bin/
^^ don't miss to include or define properties from src/main/resources/extensions/npm/npm.properties
*1): unfortunatly buggy with current node.js version
I am trying to use the flex ant task to build my Flex project.
Before using ant, I ran the mxmlc command like this:
mxmlc -load-config mxmlc_conf.xml src\project.mxml -output bin-debug +libs=<absolute_path_to>3rdparty\libs +<other_token>=<absoulte_path_to_value>
The thing is now I am supposed to use flex ant tasks and it looks like they disabled (or forgot about) the custom tokens like += as I haven't found a way to pass those to the mxmlc task.
I have tried using:
< mxmlc ...>< arg token value="..." />< /mxmlc>
but that doesn't work.
What I am trying to accomplish is to get rid of hard-coded paths in the mxmlc config-file (mxmlc_conf.xml) and at first I used the custom tokens in mxmlc but now I don't know how to pass paths as variables to the config file.
I can accept suggestions.
Thanks a lot in advance.
I'm trying to do the exact same thing (replace hard-coded paths in the config file) and I'm looking for the same solution.
It seems we might have to abandon the mxmlc task and simply use mxmlc from the command line:
<exec searchpath="true" executable="amxmlc"
dir="${project.build.outputDirectory}">
<env key="PATH"
path="${env.PATH}:/Applications/Adobe\ Flash\ Builder\ 4.5/sdks/4.5.1/bin" />
<arg value="-load-config" />
<arg value="../src/main/resources/dumpConfig.xml" />
<arg value="+libs=/absolute/path/to/3rd/party/libs" />
<arg value="-output" />
<arg
value="${project.build.outputDirectory}/${application.name}.swf" />
<arg value="../src/main/flex/${application.name}.mxml" />
</exec>
Something like this should work. I'm just hoping there's a better way (that is, a way we can actually use the mxml ant target!)
I hope that helps someone...
Try this
<target>
<replace file="mxmlc_conf.xml" token="$${libs}" value="absolute/path/to/3rdparty/libs"/>
<mxmlc ...>
<load-config filename="mxmlc_conf.xml" />
</mxmlc>
<replace file="mxmlc_conf.xml" token="absolute/path/to/3rdparty/libs" value="$${libs}"/>
</target>
This should be easy, but I can't find it. I want my .html and .swf files to be named something differently than the project name. Project name is foo, I want the outputs to be bar.html and bar.swf. Thanks.
Flextras was on the right track. You can't change the output filename (even using the "-output" compiler param) if you're compiling in Flash Builder. Not sure why.
The solution that has worked for me has been to use a bit of indirection:
use mxmlc to compile to ApplicationClass.swf
command line copy ApplicationClass.swf to YourCustomSwf.swf
command line run YourCustomSwf.swf
You can do this with either a simple (platform-dependent) build script, or with Flex Ant Tasks. I highly recommend the latter; it's easy to setup, integrates well with Flash Builder, and (as a mostly platform-independent solution) will work in a multi-team multi-OS environment. Here are the above steps as ant tasks that will perform the magic for you:
<project name="sample-build" default="run-your-swf">
<property file="${basedir}/your.properties.file"/>
<target name="compile-your-app">
<mxmlc file="${SOURCE_DIR}/ApplicationFile.mxml" compiler.debug="${IS_DEBUG}" incremental="true" failonerror="true">
<load-config filename="${DEFAULT_FLEX_CONFIG}"/>
<define name="CONFIG::DEBUG" value="${IS_DEBUG}"/>
<define name="CONFIG::FLASH_AUTHORING" value="${IS_FLASH_AUTHORING}"/>
<define name="CONFIG::IS_RELEASE" value="${IS_RELEASE}"/>
</mxmlc>
</target>
<target name="rename-your-swf" depends="compile-your-app">
<copy file="${OUTPUT_DIR}/feed/FeedComponent.swf" tofile="${OUTPUT_DIR}/YourNewSexyFilename.swf"/>
</target>
<target name="run-your-swf" depends="rename-your-swf">
<exec executable="${STANDALONE_FLASH_DEBUG_PLAYER}">
<arg line="${OUTPUT_DIR}/YourNewSexyFilename.swf"/>
</exec>
</target>
</project>
you need only define all ${VARIABLES} I've listed in "your.properties.file", like so:
FLASH_PLAYER_DEBUG=/Applications/Adobe Flash CS5/Players/Debug/Flash Player Debugger.app/Contents/MacOS/Flash Player Debugger
IS_DEBUG=true
(et cetera)
And anyway - what's in a name? A program by any other name, would be as awesome... B-)
I have a build script running successfully, but I am having a hard time running anything after aspnet_compiler completes. I want to use robocopy to copy the project to another folder. If I put the copy task above the compile (as shown below) I get the message to the console, but if I place it after the compile it is not seen. Am I missing something? Do I need to check for a return code from the compiler to call tasks after its completion?
<target name="copy" depends="init">
<echo message="This is my message for robocopy..."/>
</target>
<target name="compile" depends="copy">
<exec program="${msbuild.exe}"
commandline='MySolution.sln /p:Configuration=${Configuration};OutDir="${build.dir}\\"' />
</target>
<target name="precompile-web" depends="compile">
<exec program="${aspnet_compiler.exe}"
commandline='-v /MyProj-p "${build.dir}"\_PublishedWebsites\MyProj.Web'
/>
And yes, when/if I move the copy task below precompile-web I change the depends="precompile-web" and the compile task depends to "init".
If I understand you correctly here, you want to:
Copy the files
Compile them using MSBuild
Precompile them for the web
Is that right? I would have thought you'd want to do it this way around:
Compile the files using MSBuild
Precompile them for the web
Copy the files somewhere else (for use by IIS, etc)
If my way is correct, then I'd guess you'd want your targets to reference each other like this?
<target name="compile-and-publish" depends="compile,precompile-web,copy" />
<target name="compile">
<exec program="${msbuild.exe}" commandline='MySolution.sln /p:Configuration=${Configuration};OutDir="${build.dir}\\"' />
</target>
<target name="precompile-web">
<exec program="${aspnet_compiler.exe}" commandline='-v /MyProj-p "${build.dir}"\_PublishedWebsites\MyProj.Web' />
</target>
<target name="copy" depends="init">
<echo message="This is my message for robocopy..."/>
</target>
This way, you're not pinning each of your targets down to relying upon other targets (for re-use) but you get the order that you need to achieve the job at hand.
Any good to you?
I am just getting started with flex and am using the SDK (not Flex Builder). I was wondering what's the best way to compile a mxml file from an ant build script.
The Flex SDK ships with a set of ant tasks. More info at:
http://livedocs.adobe.com/flex/3/html/help.html?content=anttasks_1.html
Here is an example of compiling Flex SWCs with ant:
http://www.mikechambers.com/blog/2006/05/19/example-using-ant-with-compc-to-compile-swcs/
mike chambers
I would definitely go with the ant tasks that are included with Flex, they make your build script so much cleaner. Here is a sample build script that will compile and then run your flex project
<?xml version="1.0"?>
<project name="flexapptest" default="buildAndRun" basedir=".">
<!--
make sure this jar file is in the ant lib directory
classpath="${ANT_HOME}/lib/flexTasks.jar"
-->
<taskdef resource="flexTasks.tasks" />
<property name="appname" value="flexapptest"/>
<property name="appname_main" value="Flexapptest"/>
<property name="FLEX_HOME" value="/Applications/flex_sdk_3"/>
<property name="APP_ROOT" value="."/>
<property name="swfOut" value="dist/${appname}.swf" />
<!-- point this to your local copy of the flash player -->
<property name="flash.player" location="/Applications/Adobe Flash CS3/Players/Flash Player.app" />
<target name="compile">
<mxmlc file="${APP_ROOT}/src/${appname_main}.mxml"
output="${APP_ROOT}/${swfOut}"
keep-generated-actionscript="true">
<default-size width="800" height="600" />
<load-config filename="${FLEX_HOME}/frameworks/flex-config.xml"/>
<source-path path-element="${FLEX_HOME}/frameworks"/>
<compiler.library-path dir="${APP_ROOT}/libs" append="true">
<include name="*.swc" />
</compiler.library-path>
</mxmlc>
</target>
<target name="buildAndRun" depends="compile">
<exec executable="open">
<arg line="-a '${flash.player}'"/>
<arg line="${APP_ROOT}/${swfOut}" />
</exec>
</target>
<target name="clean">
<delete dir="${APP_ROOT}/src/generated"/>
<delete file="${APP_ROOT}/${swfOut}"/>
</target>
</project>
There is another option - it's called Project Sprouts.
This is a system built with Ruby, RubyGems and Rake that provides many of the features found in Maven and ANT, but with a much cleaner syntax and simpler build scripts.
For example, the ANT script shown above would look like this in Sprouts:
require 'rubygems'
require 'sprout'
desc 'Compile and run the SWF'
flashplayer :run => 'bin/SomeProject.swf'
mxmlc 'bin/SomeProject.swf' do |t|
t.input = 'src/SomeProject.as'
t.default_size = '800 600'
t.default_background_color = '#ffffff'
t.keep_generated_actionscript = true
t.library_path << 'libs'
end
task :default => :run
After installing Ruby and RubyGems, you would simply call this script with:
rake
To remove generated files, run:
rake clean
To see available tasks:
rake -T
Another great benefit of Sprouts, once installed, is that it provides project, class and test generators that will get any development box ready to run with a couple simple command line actions.
# Generate a project and cd into it:
sprout -n mxml SomeProject
cd SomeProject
# Compile and run the main debug SWF:
rake
# Generate a new class, test case and test suite:
script/generate class utils.MathUtil
# Compile and run the test harness:
rake test
If you're open to Maven, try the flex-compiler-mojo plugin:
http://code.google.com/p/flex-mojos/
Christiaan