How do I make MvcBuildViews continue to other views on error? - asp.net-mvc

I've got a handy visual studio external tool shortcut to build the current project with MvcBuildViews enabled.
Arguments: /m:2 $(ProjectFileName) /p:MvcBuildViews=true
Command Line: C:\Windows\Microsoft.NET\Framework\v4.0.30319\MSBuild.exe /m:2 "ProviderPortal.csproj" /p:MvcBuildViews=true
Anytime there is an error on a view, it stops at that one and reports it.
I want to know all the views that have errors not just stop at the first one.
How would I tell the Aspnet-Compiler to continue on errors? Or is there a way to get msbuild to instead invoke the aspnet-compiler per view rather than a one-shot call?

You can try setting ContinueOnError to ErrorAndContinue:
<Target Name="MvcBuildViews" AfterTargets="AfterBuild" Condition="'$(MvcBuildViews)'=='true'">
<AspNetCompiler VirtualPath="temp" PhysicalPath="$(WebProjectOutputDir)" ContinueOnError="ErrorAndContinue" />
</Target>
http://msdn.microsoft.com/en-us/library/ms171484.aspx

Related

How to resolve 7-zip's 'Warnings: Headers Error' from .zip created by Ant build?

I have code for creating zip file in ant build script.
<target name="zip-dist" description="archiving artifacts">
<zip destfile="${artifacts}/${zipfile}.zip" update="false" basedir="${target.dist}" includes="*.xyz-*" />
</target>
When file is being extracted using win zip right click -> Extract All... there's no warning, but while extracting with 7-zip showing 'Warnings: Headers Error' but its successful.
I know this has no effect on the output as its just a warning so suggested users to ignore it or use win-zip method.
But trust me it is impossible to make them understand and they all are keep on eating my head.
There are many users and I am banging my head repeating same thing again and again. Still they want it to be fixed.
Can I use any attribute in ant-zip target or should I use any different zipping technique in ant build?
I have searched multiple online sources, this is last hope!
Please help.
I had the same issue.
Fixed adding only one attribute, to force Zip64 extensions:
zip64Mode="always"
Try and should work for you too.
Instead of regular zip target used 7-zip to create zip.
<property name="7z.exe" value="C:/Program Files/7-Zip/7z.exe" />
<target name="zip-dist" description="archiving artifacts">
<exec executable="${7z.exe}">
<arg value="a" />
<arg value="-tzip" />
<arg value="${artifacts}/${zipfile}.zip" />
<arg value="${target.dist}/*.xyz-*" />
</exec>
</target>
As 7-zip includes all necessary information regarding header, so that warning will not occur.
Of course, 7-zip must be available in system.

Ant: How to test if a target exist (and call it not if it doesn't)?

I have a set of build files, some of them calling others -- importing them first. End of line builds may have or may not have a specific target (e.g. "copyother"). I want to call it from my main build file if that target is defined within the end-of-line build script. How can I do it?
Part of the calling script:
<!-- Import project-specific libraries and classpath -->
<property name="build.dir" value="${projectDir}/build"/>
<import file="${build.dir}/build_libs.xml"/>
...
<!-- "copyother" is a foreign target, imported in build_libs.xml per project -->
<target name="pre-package" depends=" clean,
init,
compile-src,
copy-src-resources,
copy-app-resources,
copyother,
compile-tests,
run-junit-tests"/>
I do not want every project to define "copyother" target. How can I do a conditional ant call?
I'm guessing you aren't importing the "other" build scripts into your main build.xml. (Because that wouldn't work. Ant treats imports as local.)
At the same time, you are using depends and not ant/ant call so maybe you are importing them, but one at a time.
You can't do what you want in native Ant. As you noted testing for a file is easy but a target is not. Especially if that other project isn't loaded yet. You definitely have to write a custom Ant task to accomplish what you want. Two avenues:
1) Call project.getTargets() and see if your target is there. This involves refactoring your script to use ant/antcall instead of pure depends, but doesn't feel like a hack. Writing a custom Java condition isn't hard and there is an example in the Ant manual.
2) Add a target to the current project if not already there. The new target would be a no-op. [not sure if this approach works]
For the same of completeness. Another approach is to have some target for checking the target.
The approach is discussed here: http://ant.1045680.n5.nabble.com/Checking-if-a-Target-Exists-td4960861.html (vimil's post). Check is done using scriptdef. So it is not that different from other answer(Jeanne Boyarsky), but script is easy to add.
<scriptdef name="hastarget" language="javascript">
<attribute name="targetname"/>
<attribute name="property"/>
<![CDATA[
var targetname = attributes.get("property");
if(project.getTargets().containsKey(targetname)) {
project.setProperty(attributes.get("property"), "true");
}
]]>
</scriptdef>
<target name="check-and-call-exports">
<hastarget targetname="exports" property="is-export-defined"/>
<if>
<isset property="is-export-defined"/>
<then>
<antcall target="exports" if="is-export-defined"/>
</then>
</if>
</target>
<target name="target-that-may-run-exports-if-available" depends="check-and-call-exports">
You should explore use of the typefound condition, added to ANT in 1.7. You can use it, for example, with the if task from antcontrib like this, but you have to check for a macrodef and not a taskdef due to how it works:
<if>
<typefound name="some-macrodef"/>
<then>
<some-macrodef/>
</then>
</if>
With this, ant files that have a macrodef named "some-macro-or-taskdef" will get it invoked and other ant files without it will not get an error.

ANT: How to read property setted in a foreach loop

Dear, I currently face some problem to retrieve the value of a property setted in a foreach loop. Maybe one of you could help me...
The purpose is to check if one file of a folder has been modified since the corresponding jar has been generated. This way I know if I have to generate the jar again.
What I do is to go through the folder with a foreach loop and if one file match my test, set a property to true.
The problem is that my variable doesn't seems to exist after my loop... Here is a simplified code example that has the same problem:
<target name="target">
<taskdef resource="net/sf/antcontrib/antlib.xml" classpath="${lib.dir}/ant-contrib.jar"></taskdef>
<foreach target="setVar" param="var" list="a,b"/>
<echo>myreturn in target: ${env.myreturn}</echo>
<property name="env.myreturn" value="c"/>
<echo>myreturn in second: ${env.myreturn}</echo>
</target>
<target name="setVar">
<property name="env.myreturn" value="${var}"/>
<echo>myreturn in setVar: ${env.myreturn}</echo>
</target>
The result of this code is:
target:
setVar:
[echo] myreturn in setVar: a
setVar:
[echo] myreturn in setVar: b
[echo] myreturn in target: ${env.myreturn}
[echo] myreturn in second: c
BUILD SUCCESSFUL
It seems that the variable is correctly set as it could be printed in the "setVar" target but no way to retrieve value from the calling target.
I also know it's not possible to assign a value to a property twice. But the problem doesn't even occurs... When it'll be the case I could add a check on the value of the property before to assign it to be sure it is not already initialized...
Do you have a clue on the way I can solve my problem ???
Many thanks in advance for your help :)
Try <for> task from ant-contrib instead of <foreach>. The <for> task takes advantage of Ant macro facility that came later. It works faster and is more flexible than the older <foreach> task. You are in the same project context when using <for>. That means properties set in the loop will be visible outside of the loop. Of course, normal rules for properties apply... you only get to set it once... unless you use <var> task from ant-contrib to overwrite or unset previously set properties.
Ah the joys of Ant hacking.
Not sure about your foreach problem, but can you not use the uptodate task for your requirement?
Even if I don't need it anymore thanks to sudocode, I found a solution for my question. Maybe it could be useful for someone else...
A collegue talked about the "antcallback" target of ant-contrib: it allows to return a result from a called target to the calling one. With a combination of "for" target and "antcallback" it is possible to do what I wanted to do:
<target name="target">
<taskdef resource="net/sf/antcontrib/antlib.xml" classpath="${lib.dir}/ant-contrib.jar"></taskdef>
<for param="file">
<path>
<fileset dir="../myDirectory" includes="**/*" />
</path>
<sequential>
<antcallback target="setVar" return="retValue">
<param name="file" value="#{file}"/>
</antcallback>
</sequential>
</for>
<echo>result: ${retValue}</echo>
</target>
<target name="setVar">
<property name="retValue" value="${file}"/>
</target>
"file" contains the name of the file in the directory. It is given to the called target as parameter with value "#{file}" ('#' necessary due to "for" target implementation).
At the end of the main target, ${retValue} contains the first value setted by the "setVar" target. No error is thrown when trying to set it multiple times, so it's not necessary to check if variable has already been instantiated before to set it in "setVar" target.
The <foreach> task uses the same logic as <antcall> under the covers, and any proprrties set inside a target invoked by <antcall> do not have scope beyond the execution of that target.
In other words, the env.myreturn property that you define in the setVar target is lost as soon as execution of that target completes.
This sort of scripting really isn't what Ant is designed for. The Ant-contrib library tries to patch up the holes, but it's still bending it way out of shape.
If you need to write such scripts, and want to use Ant tasks to achieve them, have a look at Gradle instead. It's a rather lovely blend of Groovy (for scripting) and Ant (for the tasks).
The other approaches here (<for>, <var>, <groovy>properties.put(....)</groovy>, <property>, <antcallback>) did not work with ANT 1.9.4, so I used the file system similar to this (pseudocode):
<target name="outer">
<for> <antcall target="inner" /> </for>
<loadproperties srcfile="tmpfile.properties" />
<echo message="${outerprop}" />
</target>
<target name="inner">
<!-- did not work: -->
<!--
<property name="outerprop" value="true" />
<var name="outerprop" value="true" />
<groovy>properties.put('outerprop','true')</groovy>
<antcallback target="setouterprop" />
-->
<echo message="outerprop=true" file="tmpfile.properties" />
</target>
Maybe the other approaches did not work because of my <antcall>, but I need it here. (outerprop is initially unset)

Ant - conditional statement

I'm using ant to build my app, and I want to have single process for dev/qa/prod versions of the app. I want to do be able to specify the build target from command line:
ant -Dbuildtarget=dev|qa|prod
and in build.xml check for the value of buildtarget and set an application specific base URL property based on the buildtarget specified by the user. I will subsequently set the correct runtime param using
<copy file="pre.app.properties" tofile="./app.properties" overwrite="true">
<filterset>
<filter token="BASE_URL" value="${baseurl}" />
</filterset>
</copy>
What I am stuck on is how to express this in and build.xml ?
if buildtarget=='dev'
baseurl="http://my_dev_url"
else if buildtarget=='qa'
baseurl="http://my_qa_url"
else if buildtarget=='prod'
baseurl="http://my_prod_url"
I've searched around, but this seems to be difficult to do in ant. Any ideas ?
When starting your ant script with ant -Dbuildtarget=dev|qa|prod it's as simple as =
<project >
<property name="baseurl" value="http://my_${buildtarget}_url"/>
<echo>$${baseurl} => ${baseurl}</echo>
</project>
The buildtarget property can be used as dynamic part of the baseurl property.Afterwards ${buildurl} can be used for further processing..
Perhaps you should try using the condition task of ant?

What are the custom targets you all run when using ant to build project?

I am thinking of running this custom targets to find out more about my project build status
- jalopy
- jdepend
- cvs tagdiff report
- custom task for NoUnit
- generate UML diagram. ESS-Model
What are your views?
I think that it's a great idea and use it myself. That way I'll never forget to run it.
I also keep the reports for a decent amount of time and eventually create a spreadsheet of "progress".
In your main ant task - call another task to do "whatever"
and
JDepend.xml ...
<target name="statsAll">
<!-- master file that describes where everything is -->
<property file="./ant/ant-global.properties" prefix="ant-global" />
<tstamp>
<format property="gen.time" pattern="yyyyMMdd_hh"/>
</tstamp>
<echo message="LOG:./ant/logs/jdepend.${version.FILETAG}.${gen.time}.rpt"/>
<!-- generate stats to see if we're improving -->
<jdepend
outputfile="./ant/logs/jdepend.${version.FILETAG}.${gen.time}.rpt" >
<exclude name="java.*"/>
<exclude name="javax.*"/>
<classespath>
<pathelement location="./jar" />
</classespath>
<classpath location="./jar" />
</jdepend>
</target>
<target name="doJDepend" depends="getVersion,statsAll">
<echo message="FTP'ing report"/>
<ftp verbose="yes" passive="yes" depends="yes"
remotedir="/videojet/metrics" server="xxxxx"
userid="xxxx" password="xxxxx"
binary="no"
systemTypeKey="UNIX">
<fileset dir="./ant/logs/" casesensitive="no">
<include name="**/jdepend.${version.FILETAG}*.rpt"/>
<exclude name="**/*.txt"/>
</fileset>
</ftp>
</target>
Magic build machine
I second the 'good idea' part, although for a project of reasonable size you might want to make it part of an automated build, like one of the CI Servers (Bamboo, Contiuum).
You might also consider a code coverage tool to see how your test coverage is going.
This will ensure the reports get run on a regular basis, could give you somewhere to publish them and won't slow down the developer's quick turnaround development cycle.
I also think some reports about your project are a good idea. My template-project for an ant-build-script (Antiplate) has at the moment the following reports: Junitreport, emma-report, PMD, CPD and Checkstyle. I'm thinking about including a JDepend-report.
At work we use these templates and using Hudson as continuous-integration-system. Hudson creates wonderful graphs for these reports and how the measures changed with the builds.

Resources