I have been struggling trying to figure out how to conditionally include Flex libraries in an ant build based on a property that is set on the command line. I have tried a number of approaches with the <condition/> task, but so far have not gotten it to work. Here is where I am currently.
I have an init target that includes condition tasks like this:
<condition property="automation.libs" value="automation.qtp">
<equals arg1="${automation}" arg2="qtp" casesensitive="false" trim="true"/>
</condition>
The purpose of this task is to set a property that determines the name of the patternset to be used when declaring the implicit fileset on a mxmlc or compc task. The pattern set referenced above is defined as:
<patternset id="automation.qtp">
<include name="automation*.swc"/>
<include name="qtp.swc"/>
</patternset>
The named patternset is then referenced by the mxmlc or compc task like this:
<compc>
<compiler.include-libraries dir="${FLEX_HOME}/frameworks/libs" append="true">
<patternset refid="${automation.libs}"/>
</compiler.include-libraries>
</compc>
This doesn't appear to work. At least the SWC size does not indicate that the additional automation libraries have been compiled in. I want to be able to specify a command line property that determine which patternset to use for various types of builds.
Does anyone have any ideas about how to accomplish this? Thanks!
If you can't get <patternset> to work correctly, you might want to take a look at the <if> <then> and <else> tasks provided by ant-contrib. We ended up doing something like this:
<target name = "build">
<if>
<equals arg1="automation.qtp" arg2="true"/>
<then>
<!--
- Build with QTP support.
-->
</then>
<else>
<!--
- Build without QTP support.
-->
</else>
</if>
</target>
There is some duplication of build logic between the if and else branch, but you can factor some of that out if you wrap <mxmlc> with a macrodef.
The mxmlc task supports loading configuration files <load-config filename="path/to/flex-config.xml" />. So, generate the config xml on the fly, by combining the echoxml task and if-then-else.
<echoxml file="path/to/flex-config.xml">
<flex-config>
<compiler>
<library-path append="true">
<path-element>${lib.qtp}</path-element>
</library-path>
</compiler>
</flex-config>
</echoxml>
If your needs are more complicated, you could even generate several xml configs and <load-config ... /> them all.
Personally, I find any logic very terse and ugly to write using Ant's conditions or if-then-else, XML is not a pretty language to use for programming. Luckily, it's possible to use more flexible approach - write a script to produce the config xml, before calling mxmlc. E.g. use the script task with your favorite scripting language
<script language="javascript">
<![CDATA[
// Create your XML dynamically here.
// Write that XML to an external file.
// Later, feed that file to mxmlc using `<load-config ... />`.
]]>
</script>
Related
I am modifying some existing projects that uses QT (version 5.10). I am updating them to use better, more concise msbuild syntax (Target Visual Studio 2015) on windows.
One project has about 170 header files, of which about 135 header files need to be run through MOC.exe.
Therefore I wrote a custom target to send 135 files to moc.exe. But the msbuild syntax to tell Moc which files to process is quite long.
i.e.
<QtMocs Include="A.h;
B.h;
C.h;
D.h;
etc...
I tried sending ALL of the header files through to moc.exe. But if a header file doesn't have Q_OBJECT, then moc.exe emits a warning about not needing to moc the header file. And to add insult to injury it still emits a cpp file, even though nothing needed to be moc'd.
So I'd like to write a nice short (one line?) concise way to tell QT to moc only the headers that are needed.
Is this possible?
So after two days with no response, I decided to write my own solution, which works really well. I wrote a custom task for MSBuild. It takes an array of ProjectItem's that is supposed to point to all the header files in your project. Then for each file in the array, it opens the files, searches for Q_OBJECT and if found saves off the Item into an output array. That output array is then queried later on and sent to moc.exe.
<!-- Task to automatically discover header files that need to be run through QT's MOC.exe compiler.
It does this by examing each file and checking if 'Q_OBJECT' is in the file. -->
<UsingTask TaskName="FindFilesForQtMoc" TaskFactory="CodeTaskFactory" AssemblyFile="$(MSBuildToolsPath)\Microsoft.Build.Tasks.v4.0.dll" >
<ParameterGroup>
<Files ParameterType="Microsoft.Build.Framework.ITaskItem[]" Required="true" />
<MocFiles ParameterType="Microsoft.Build.Framework.ITaskItem[]" Output="true" />
</ParameterGroup>
<Task>
<Using Namespace="System" />
<Using Namespace="System.IO" />
<Using Namespace="System.Diagnostics" />
<Code Type="Fragment" Language="cs">
<![CDATA[
var result = new List<Microsoft.Build.Framework.ITaskItem>();
foreach(var item in Files)
{
String filePath = item.GetMetadata("FullPath");
var content = File.ReadAllText(filePath);
if (content.Contains("Q_OBJECT"))
{
result.Add(item);
}
}
MocFiles = result.ToArray();
]]>
</Code>
</Task>
</UsingTask>
I call the task like this:
<FindFilesForQtMoc Files="#(ClInclude)" >
<Output ItemName="FileForMoc" TaskParameter="MocFiles" />
</FindFilesForQtMoc>
<Message Text="Moc: %(FileForMoc.Identity)" />
Therefore I only have to declare all my header files in my .vcxproj like this:
<ClInclude Include="*.h" />
Which is way better than explicitly declaring each and every file that needs moc.exe.
What is the difference between AsyncTaskTarget and AsyncWrapper?
Which is better?
I have seen that AsyncWrapper has more config options (like queueLimit, overflowAction & more) which is important for me (I don't want logs to get discarded, even if more than 10000 logs buffered, since I am working on a website for some big company).
So, is that the only difference?
Why then we even have something like AsyncTaskTarget?
Moreover, what happens if I combined both AsyncTaskTarget & AsyncWrapper with something like this:
CustomTargetExtendingAsyncTaskTarget customTarget = CustomTargetExtendingAsyncTaskTarget();
AsyncTargetWrapper asyncTargetWrapper = new AsyncTargetWrapper(customTarget, 100000, AsyncTargetWrapperOverflowAction.Grow);
is this a bad idea?
In summary:
The AsyncTarget is a target to wrap around other targets to give them Async behavior. Good to know, the async=true that could be applied in the nlog.config is internally also the AsyncWrapper.
For example, writing async to a file:
<target name="target2" xsi:type="AsyncWrapper">
<target name ="target1" xsi:type="File"
fileName="c:/temp/test.log" layout="${message}"
keepFileOpen="true" />
</target>
The AsyncTaskTarget is an (abstract) base class for creating custom targets (e.g. in C#) with async behavior. You cannot use the AsyncTaskTarget in your nlog.config
Rolf describes it nicely:
(from https://github.com/NLog/NLog/issues/2872)
AsyncTaskTarget is a base-class just like TargetWithLayout for creating your own custom Target. It makes it easier to make one chain of tasks with timeout-handling. By default it will ensure the Logger is not stalled, as it just writes to the internal-queue (and schedules a writer-task if none is active).
I have two test groups which are dependent on another group.
<dependencies>
<group name="search" depends-on="login" />
<group name="addnew" depends-on="login" />
</dependencies>
Which one out of the two groups (search, addnew) should ideally get executed first? For me, the group addnew is getting executed first all the time, which I don't want to happen. I want search to get executed and then addnew to get executed, once login is done. Also, I have set "preserve-order" for the test as true. Any suggestions?
If you want search to get executed first, then add new is also dependent on search group in that case. You can specify a list of groups in the depends-on list. Try with depends-on="login search" or you can let search depend on login and make add new depend on search to guarantee execution order.
Quote from documentation: "By default, TestNG will run your tests in the order they are found in the XML file. If you want the classes and methods listed in this file to be run in an unpredictible order, set the preserve-order attribute to false:"
<test name="Regression1" preserve-order="false">
<class name="test.Test1">
<methods>
<include name="m1" />
<include name="m2" />
</methods>
</class>
<class name="test.Test2" />
I'm responsible for allowing unit tests for one of ETL components.I want to acomplish this using testNG with generic java test class and number of test definitions in testng.xmlpassing various parameters to the class.Oracle and ETL guys should be able to add new tests without changing the java code, so we need to use xml suite file instead of annotations.
Question
Is there a way to group tests in testng.xml?(similarly to how it is done with annotations)
I mean something like
<group name="first_group">
<test>
<class ...>
<parameter ...>
</test>
</group>
<group name="second_group">
<test>
<class ...>
<parameter ...>
</test>
</group>
I've checked the testng.dtd as figured out that similar syntax is not allowed.But is therea workaround to allow grouping?
Thanks in advance
You can specify groups within testng.xml and then run testng using -groups
<test name="Regression1">
<groups>
<run>
<exclude name="brokenTests" />
<include name="checkinTests" />
</run>
</groups>
....
No, this is not possible at the moment.
As a rule of thumb, I don't like adding information in XML that points into Java code, because refactorings might silently break your entire build.
For example, if you rename a method or a class name, your tests might start mysteriously breaking until you remember you need to update your XML as well.
Feel free to bring this up on the testng-users mailing-list and we can see if there's interest for such a feature.
--
Cedric
I want to build an ant script that does exactly the same compilation actions on a Flash Builder 4 (Gumbo) project as the Project->Export Release Build... menu item does. My ant-fu is reasonably strong, that's not the issue, but rather I'm not sure exactly what that entry is doing.
Some details:
I'll be using the 3.x SDK (say, 3.2 for the sake of specificity) to build this.
I'll be building on a Mac, and I can happily use ant, make, or some weird shell script stuff if that's the way you roll.
Any useful optimizations you can suggest will be welcome.
The project contains a few assets, MXML and actionscript source, and a couple of .swcs that are built into the project (not RSL'd)
Can someone provide an ant build.xml or makefle that they use to build a release .swf file from a similar Flex project?
One quick way to know the compiler options is to add this tag into your compiler options:
-dump-config your/drive/to/store/the/xmlfile.xml
This will output the entire ant compiler options and you can copy off the parts you want to keep.
HellFire Compiler Daemon (http://bytecode-workshop.com/) can generate build.xml directly from the compiler calls made by Flex/Flash Builder. That means your ant script produces SWCs and SWFs based on the exact same set of compiler settings that you set in Flex/Flash Builder.
Also, check out this blog:
http://stopcoding.wordpress.com/2010/01/15/ant-tasks-for-hfcd-now-available-2/
I had some issues with the Adobe Flex Ant tasks a while back, so I ended up using an exec call to the mxmlc compiler with a boatload of options and we've just built upon it from there. There are a few nagging doubts that what I do with the build.xml is not exactly the same that FB3 (what we have) does, but this might be enough to help get you started... you say your ant-fu is reasonably strong, so I'll skip over most of my build file and let you piece together the pieces.
<!--flex stuff-->
<property name="dir.flex.sdk" value="${system.build.flex.sdk}"/>
<property name="dir.flex.home" value="${dir.abc}/flex/sdks/${dir.flex.sdk}"/>
<property name="dir.flex.projects" value="${dir.abcd_plat}/webapp/flexprojects/"/>
<property name="dir.modules" value="${dir.war}/modules/"/>
<property name="FLEX_HOME" value="${dir.flex.home}"/>
<property name="APP_ROOT" value="${dir.war}"/>
<property name="flexc.exe" value="This should be set in the build-${os.family}.xml file"/>
<property name="asdoc.exe" value="This should be set in the build-${os.family}.xml file"/>
<property name="optimizer.exe" value="This should be set in the build-${os.family}.xml file"/>
<property name="flex.mxmlc" value="${dir.flex.home}/bin/${flexc.exe}"/>
<property name="flex.compc" value="${dir.flex.home}/bin/${compc.exe}"/>
<property name="flex.asdoc" value="${dir.flex.home}/bin/${asdoc.exe}"/>
<property name="flex.optimizer" value="${dir.flex.home}/bin/${optimizer.exe}"/>
<property name="flex.options.warnings" value="false"/>
<!--options that are used in common for compiling all .swc and .swf files-->
<property name="flex.meta.1" value="-creator 'MyCorp.' -publisher 'MyCorp.'"/>
<property name="flex.meta.2" value="-title MegaProduct -description http://ourURL.com"/>
<property name="flex.meta.props" value="${flex.meta.1} ${flex.meta.2}"/>
<property name="debug.options" value="-optimize=true -debug=false"/>
<property name="common.flex" value="-as3 -target-player=9.0.124 -warnings=${flex.options.warnings}"/>
<property name="license.flex3" value="(put your own here)"/>
<property name="common.fixed" value="-license=flexbuilder3,${license.flex3} -sp ${dir.war} -library-path+=${dir.webinf}/lib"/>
<property name="flex.common.args" value="${flex.meta.props} ${debug.options} ${common.flex} ${common.fixed}"/>
<!--this is currently unused, but if we make a debug version, this can be set to make a separate output file-->
<property name="swf.suffix" value=""/>
<!--=================================================================================
MACRODEFs
-->
<!--this is used to extract .swf files from 3rd party .swc libraries, in order to do dynamic linking-->
<macrodef name="extract-flex-lib" description="For modularizing flex compilation">
<attribute name="swc-lib" default="NOT SET"/>
<sequential>
<!--use a copy task - it can get the file out of the zip, and rename it at the same time-->
<copy todir="${dir.war}" preservelastmodified="true">
<zipfileset src="${dir.webinf}/lib/#{swc-lib}.swc">
<patternset>
<include name="library.swf"/>
</patternset>
</zipfileset>
<mapper type="glob" from="library.swf" to="#{swc-lib}-debug.swf"/>
</copy>
<!--run the flex optimizer on the extracted .swf - note the as3 metadata that's kept, it's required-->
<exec executable="${flex.optimizer}" failonerror="true">
<arg line="-keep-as3-metadata='Bindable,Managed,ChangeEvent,NonCommittingChangeEvent,Transient'"/>
<arg line="-input #{swc-lib}-debug.swf -output #{swc-lib}.swf"/>
</exec>
<!--delete the unoptimzed swf, don't need it anymore-->
<delete file="#{swc-lib}-debug.swf"/>
</sequential>
</macrodef>
<!--this is used to compile our internal flex modules-->
<macrodef name="flexc-mxml" description="For building the flex modules during flex compilation">
<attribute name="name" default=""/>
<attribute name="mxml.args" default="${flex.common.args} ${module.args}"/>
<attribute name="sourcePath" default=""/>
<attribute name="destPath" default=""/>
<sequential>
<echo message=" Compiling with mxmlc: #{name}"/>
<exec executable="${flex.mxmlc}" failonerror="true">
<arg line="#{mxml.args} #{sourcePath} -output #{destPath}"/>
</exec>
</sequential>
</macrodef>
<!--this is used to compile our subprojects under abcd_plat/webapp/flexprojects-->
<macrodef name="flexc-subproject" description="For compiling the flex subprojects into .swc files">
<attribute name="name" default=""/>
<attribute name="xtra.args" default=""/>
<sequential>
<echo/>
<echo message=" Compiling subproject: #{name}"/>
<xslt in="${dir.flex.projects}/#{name}/.flexLibProperties" out="${dir.flex.projects}/#{name}/src/manifest.xml" style="${dir.war}/build-manifest-style.xsl"/>
<exec executable="${flex.compc}" failonerror="true">
<arg line="-load-config+=${dir.flex.projects}/#{name}/include-files.xml"/>
<arg line="-namespace http://#{name}.ourURL.com ${dir.flex.projects}/#{name}/src/manifest.xml"/>
<arg line="-include-namespaces http://#{name}.ourURL.com #{xtra.args}"/>
<arg line="-library-path+=${dir.webinf}/lib -sp ${dir.flex.projects}/#{name}/src -output ${dir.webinf}/lib/#{name}.swc"/>
</exec>
</sequential>
</macrodef>
<!--=================================================================================
This is where all the compilation is done. The actual work is split among
several different tasks in order to organize them better.
This target uses the html-wrapper task defined in flexTasks.jar - see taskdef above.
-->
<target name="flexcompile" depends="flexc-modularize" description="Builds the Flex sources" unless="flexc.notRequired.main">
<echo message="Compiling MegaProduct Flex application on OS family: ${os.family}"/>
<echo message=" mxmlc is: ${flex.mxmlc}"/>
<echo message=" compc is: ${flex.compc}"/>
<!--compile flex sub-projects first (main application depends on these extra libraries)-->
<antcall target="flexc-projects"/>
<!--compile the main MegaProduct application-->
<antcall target="flexc-main"/>
<!--compile the foobar stuff, which link against the main app. these foorbars are modules
inside a subproject, so they are handled differently from other flex projects and modules-->
<antcall target="flexc-foorbars"/>
<!--generate the html wrapper for the .swf-->
<html-wrapper title="MyCorp MegaProduct" application="app_name" swf="app_name" history="false" template="express-installation"/>
</target>
<target name="flexc-projects">
<!--the name must match the name of the folder exactly, also they are not in parallel as some depend on others-->
<flexc-subproject name="Dockable"/>
<flexc-subproject name="EXRibbon" xtra.args="-source-path+=${dir.flex.projects}/EXRibbon/locale/en_US/"/>
<!--note: MPLib does some extra stuff with the image dir in order to link against images correctly-->
<copy todir="${dir.flex.projects}/MPLib/src/image"><fileset dir="${dir.war}/image"/></copy>
<flexc-subproject name="MPLib"/>
<delete dir="${dir.flex.projects}/MPLib/src/image"/>
</target>
<target name="flexc-main">
<!--the link report is used to create the symbols in the main swf, and modules link against it-->
<property name="link.report" value="${dir.war}/abc_link_report.xml"/>
<!--modular.args is set in flexc-modularize. If not set, this sets it to an empty property-->
<property name="modular.args" value=""/>
<!--set up options specific for the main part and for the modules-->
<property name="main.args" value="-link-report=${link.report} ${modular.args}"/>
<property name="module.args" value="-load-externs=${link.report}"/>
<!--compile abc_flex.mxml here-->
<echo message="Compiling abc_flex application, sub-applications and modules..."/>
<echo/>
<flexc-mxml name="abc_flex" mxml.args="${flex.common.args} ${main.args}"
sourcePath="${dir.war}/abc_flex.mxml" destPath="${dir.war}/abc_flex${swf.suffix}.swf"/>
<!--compile MPMainSubApplication.mxml sub-application here-->
<flexc-mxml name="MPMainSubApplication" mxml.args="${flex.common.args} ${main.args}"
sourcePath="${dir.war}/MPMainSubApplication.mxml" destPath="${dir.war}/MPMainSubApplication.swf"/>
<!--compile internal modules next - just add new modules to the list here -->
<parallel> <!--do in parallel - it goes faster and they don't depend on each other-->
<property name="dir.module.src" value="${dir.war}/module/"/>
<flexc-mxml name="module1" sourcePath="${dir.module.src}/editor/Editor.mxml" destPath="${dir.module.src}/editor/Editor.swf" />
<flexc-mxml name="RunModule" sourcePath="${dir.module.src}/run/RunModule.mxml" destPath="${dir.module.src}/run/RunModule.swf" />
<!--<flexc-mxml name="JobManager" sourcePath="${dir.module.src}/jobmanager/JobManager.mxml" destPath="${dir.module.src}/jobmanager/JobManager.swf" />-->
<flexc-mxml name="Editor2" sourcePath="${dir.module.src}/edit/Editor.mxml" destPath="${dir.module.src}/edit/Editor.swf" />
</parallel>
</target>
NOTES:
I'm not sure if it's a good idea or not, but we just put the .swc files to include with our Java middle tier libs in WEB-INF/lib, so whenever we add a new flex lib to source control we just drop it in there. The compilation is done in the macros, and most of the parameters are defined as properties in the top section. The targets split the work because our app is quite large; you probably don't need those but it's an example of doing modules within sub-projects plus the link-report and follows the way a sub-project is referenced from the main application (I think). Our build machine is linux, so that's why the flexc.exe property (and others) are defined that way - it gets set at runtime. Names have been munged by hand for this answer, so please double-check for typos if you cut-n-paste anything.
Also, the incremental compilation isn't actually used; it seems to be buggy. Ditto for the modularization stuff, so I didn't include that target.
I built all of this myself so I'm rather proud of it, but if there's anything that looks iffy or smells bad, please feel free to let me know. Thanks!