I want to set Assembly Version of C# project in csproj file with a self generated task.
I want to set Assembly Version to:
Major Version -> Project version: for example 3
Minor Version -> 0
Build Number -> Year + Calendarweek
Revision -> Current day of week
My idea was the following code.
But currently it is not working.
Any ideas what I should change?
<UsingTask TaskName="DetectAssemblyVersion" TaskFactory="CodeTaskFactory" AssemblyFile="$(MSBuildToolsPath)\Microsoft.Build.Tasks.v4.0.dll">
<ParameterGroup>
<Result ParameterType="System.String" Output="true" />
</ParameterGroup>
<Task>
<Code Type="Fragment" Language="cs">
<![CDATA[
string year = System.DateTime.Now.ToString("yy");
int dayOfWeek = (int) System.DateTime.Now.DayOfWeek;
System.Globalization.DateTimeFormatInfo dfi = System.Globalization.DateTimeFormatInfo.CurrentInfo;
System.Globalization.Calendar cal = dfi.Calendar;
string calendarWeek = cal.GetWeekOfYear(System.DateTime.Now, dfi.CalendarWeekRule,
dfi.FirstDayOfWeek).ToString();
Result = "3.0." + year + calendarWeek + "."+ dayOfWeek.ToString();
Log.LogMessage(MessageImportance.High, "detect of current version: " + Result);
]]>
</Code>
</Task>
</UsingTask>
<Target Name="TestBuild" AfterTargets="Build">
<DetectAssemblyVersion>
<Output PropertyName="AssemblyVersion" TaskParameter="Result" />
</DetectAssemblyVersion>
<Message Importance="high" Text="new version: $(AssemblyVersion)" />
</Target>
Is there a simple way of taking the value of a property and then copy it to another property with certain characters replaced?
Say propA=This is a value. I want to replace all the spaces in it into underscores, resulting in propB=This_is_a_value.
Here is the solution without scripting and no external jars like ant-conrib:
The trick is to use ANT's resources:
There is one resource type called "propertyresource" which is like a source file, but provides an stream from the string value of this resource. So you can load it and use it in any task like "copy" that accepts files
There is also the task "loadresource" that can load any resource to a property (e.g., a file), but this one could also load our propertyresource. This task allows for filtering the input by applying some token transformations. Finally the following will do what you want:
<loadresource property="propB">
<propertyresource name="propA"/>
<filterchain>
<tokenfilter>
<filetokenizer/>
<replacestring from=" " to="_"/>
</tokenfilter>
</filterchain>
</loadresource>
This one will replace all " " in propA by "_" and place the result in propB. "filetokenizer" treats the whole input stream (our property) as one token and appies the string replacement on it.
You can do other fancy transformations using other tokenfilters: http://ant.apache.org/manual/Types/filterchain.html
Use the propertyregex task from Ant Contrib.
I think you want:
<propertyregex property="propB"
input="${propA}"
regexp=" "
replace="_"
global="true" />
Unfortunately the examples given aren't terribly clear, but it's worth trying that. You should also check what happens if there aren't any underscores - you may need to use the defaultValue option as well.
If ant-contrib isn't an option, here's a portable solution for Java 1.6 and later:
<property name="before" value="This is a value"/>
<script language="javascript">
var before = project.getProperty("before");
project.setProperty("after", before.replaceAll(" ", "_"));
</script>
<echo>after=${after}</echo>
In case you want a solution that does use Ant built-ins only, consider this:
<target name="replace-spaces">
<property name="propA" value="This is a value" />
<echo message="${propA}" file="some.tmp.file" />
<loadfile property="propB" srcFile="some.tmp.file">
<filterchain>
<tokenfilter>
<replaceregex pattern=" " replace="_" flags="g"/>
</tokenfilter>
</filterchain>
</loadfile>
<echo message="$${propB} = "${propB}"" />
</target>
Output is ${propB} = "This_is_a_value"
Use some external app like sed:
<exec executable="sed" inputstring="${wersja}" outputproperty="wersjaDot">
<arg value="s/_/./g"/>
</exec>
<echo>${wersjaDot}</echo>
If you run Windows get it googling for "gnuwin32 sed".
The command s/_/./g replaces every _ with .
This script goes well under windows. Under linux arg may need quoting.
Two possibilities :
via script task and builtin javascript engine (if using jdk >= 1.6)
<project>
<property name="propA" value="This is a value"/>
<script language="javascript">
project.setProperty('propB', project.getProperty('propA').
replace(" ", "_"));
</script>
<echo>$${propB} => ${propB}</echo>
</project>
or using Ant addon Flaka
<project xmlns:fl="antlib:it.haefelinger.flaka">
<property name="propA" value="This is a value"/>
<fl:let> propB := replace('${propA}', '_', ' ')</fl:let>
<echo>$${propB} => ${propB}</echo>
</project>
to overwrite exisiting property propA simply replace propB with propA
Here's a more generalized version of Uwe Schindler's answer:
You can use a macrodef to create a custom task.
<macrodef name="replaceproperty" taskname="#{taskname}">
<attribute name="src" />
<attribute name="dest" default="" />
<attribute name="replace" default="" />
<attribute name="with" default="" />
<sequential>
<loadresource property="#{dest}">
<propertyresource name="#{src}" />
<filterchain>
<tokenfilter>
<filetokenizer/>
<replacestring from="#{replace}" to="#{with}"/>
</tokenfilter>
</filterchain>
</loadresource>
</sequential>
</macrodef>
you can use this as follows:
<replaceproperty src="property1" dest="property2" replace=" " with="_"/>
this will be pretty useful if you are doing this multiple times
Adding an answer more complete example over a previous answer
<property name="propB_" value="${propA}"/>
<loadresource property="propB">
<propertyresource name="propB_" />
<filterchain>
<tokenfilter>
<replaceregex pattern="\." replace="/" flags="g"/>
</tokenfilter>
</filterchain>
</loadresource>
Just an FYI for answer Replacing characters in Ant property - if you are trying to use this inside of a maven execution, you can't reference maven variables directly. You will need something like this:
...
<target>
<property name="propATemp" value="${propA}"/>
<loadresource property="propB">
<propertyresource name="propATemp" />
...
Properties can't be changed but antContrib vars (http://ant-contrib.sourceforge.net/tasks/tasks/variable_task.html ) can.
Here is a macro to do a find/replace on a var:
<macrodef name="replaceVarText">
<attribute name="varName" />
<attribute name="from" />
<attribute name="to" />
<sequential>
<local name="replacedText"/>
<local name="textToReplace"/>
<local name="fromProp"/>
<local name="toProp"/>
<property name="textToReplace" value = "${#{varName}}"/>
<property name="fromProp" value = "#{from}"/>
<property name="toProp" value = "#{to}"/>
<script language="javascript">
project.setProperty("replacedText",project.getProperty("textToReplace").split(project.getProperty("fromProp")).join(project.getProperty("toProp")));
</script>
<ac:var name="#{varName}" value = "${replacedText}"/>
</sequential>
</macrodef>
Then call the macro like:
<ac:var name="updatedText" value="${oldText}"/>
<current:replaceVarText varName="updatedText" from="." to="_" />
<echo message="Updated Text will be ${updatedText}"/>
Code above uses javascript split then join, which is faster than regex. "local" properties are passed to JavaScript so no property leakage.
Or... You can also to try Your Own Task
JAVA CODE:
class CustomString extends Task{
private String type, string, before, after, returnValue;
public void execute() {
if (getType().equals("replace")) {
replace(getString(), getBefore(), getAfter());
}
}
private void replace(String str, String a, String b){
String results = str.replace(a, b);
Project project = getProject();
project.setProperty(getReturnValue(), results);
}
..all getter and setter..
ANT SCRIPT
...
<project name="ant-test" default="build">
<target name="build" depends="compile, run"/>
<target name="clean">
<delete dir="build" />
</target>
<target name="compile" depends="clean">
<mkdir dir="build/classes"/>
<javac srcdir="src" destdir="build/classes" includeantruntime="true"/>
</target>
<target name="declare" depends="compile">
<taskdef name="string" classname="CustomString" classpath="build/classes" />
</target>
<!-- Replacing characters in Ant property -->
<target name="run" depends="declare">
<property name="propA" value="This is a value"/>
<echo message="propA=${propA}" />
<string type="replace" string="${propA}" before=" " after="_" returnvalue="propB"/>
<echo message="propB=${propB}" />
</target>
CONSOLE:
run:
[echo] propA=This is a value
[echo] propB=This_is_a_value
I am using MSBuild.
I am getting the value of the Person_1 through the $(Person_1). How can I get the value of the Name subelement of Person_2? I need the syntax.
<PropertyGroup>
<Person_1>Bob</Person_1>
<Person_2>
<Name>Bob</Name>
</Person_2>
</PropertyGroup>
RE: https://msdn.microsoft.com/en-us/library/ms171458.aspx
A property that contains XML is simply that. You cannot access parts of the content just because it is XML. To understand this do the following;
<PropertyGroup>
<MyProperty>
<PropertyContentXML>
<InnerXML1>Blablabla</InnerXML1>
<InnerXML2>More blablabla</InnerXML2>
</PropertyContentXML>
</MyProperty>
</PropertyGroup>
<Target Name="Build">
<Message Text="$(MyProperty)" />
</Target>
The output of this will be:
<PropertyContentXML xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<InnerXML1>Blablabla</InnerXML1>
<InnerXML2>More blablabla</InnerXML2>
</PropertyContentXML>
You are mixing Properties and ItemGroups.
Properties are simple named values, ItemGroups are items with an identity and with properties. You can not use both in the same way.
Properties are defined as :
<PropertyGroup>
<name>value</name>
</Propertygroup>
and are accessed by using the $(name) syntax.
Item groups are defined as:
<ItemGroup>
<Item Include="item1">
<ItemPropery>value</ItemProperty>
</Item>
</ItemGroup>
and are accessed by using this syntax: %(Item.ItemProperty).
See also this reference for the 'intuitive' syntax
You'll need something advanced, like an inline task:
<UsingTask TaskName="TransformXmlToItem"
TaskFactory="CodeTaskFactory"
AssemblyName="Microsoft.Build.Tasks.Core">
<ParameterGroup>
<Xml Required="true"/>
<Elements ParameterType="Microsoft.Build.Framework.ITaskItem[]" Output="true"/>
</ParameterGroup>
<Task>
<Reference Include="System.Xml" />
<Using Namespace="System.Collections.Generic" />
<Using Namespace="System.Xml" />
<Code Type="Fragment" Language="cs">
<![CDATA[
using (var xr = new XmlTextReader(Xml, XmlNodeType.Element,
new XmlParserContext(null, null, null, XmlSpace.Default))) {
xr.Namespaces = false;
xr.MoveToContent();
var items = new List<ITaskItem>();
while (!xr.EOF) {
if (xr.NodeType == XmlNodeType.Element) {
var item = new TaskItem(xr.Name);
var text = xr.ReadElementContentAsString();
if (!string.IsNullOrWhiteSpace(text)) {
item.SetMetadata("text", text);
}
}
xr.Read();
}
Elements = items.ToArray();
}
]]>
</Code>
</Task>
The task reads the XML elements and creates items from it. The text is transformed into metadata.
You can then write a task like this:
<Target Name="DeconstructPropertyXml">
<TransformXmlToItem Xml="$(Person_2)">
<Output TaskParameter="Elements" ItemName="Person_2I"/>
</TransformXmlToItem>
<Message Text="%(Person_2I.Identity) = %(Person_2I.text)" Importance="high"/>
</Target>
Which should just output Name = Bob.
The same way you could add additional metadata from attributes, etc.
Running in debug from VS 2013.2RTM Pro, MVC 5.1 app.
If the compilation mode is set to debug="true" it is supposed to disable Bundling and minification but it does not. When I examine the View source on a page the styles and scripts are bundled.
<script src="/bundles/modernizr?v=K-FFpFNtIXjnmlQamnX3qHX_A5r984M2xbAgcuEm38iv41"></script>
If I set BundleTable.EnableOptimizations = false; in the BundleConfig.cs it does disable Bundling and minification but that is not how it is supposed to work. I shouldn't have to remember to toggle the EnableOptimizations setting!
Things are working properly in VS 2012 MVC 4 apps.
Is this a MVC 5.1 bug? Has anyone else had this problem? Is there a way to get debug to disable the Bundling and minification?
web.config:
<system.web>
<authentication mode="None" />
<compilation debug="true" targetFramework="4.5" />
<httpRuntime targetFramework="4.5" useFullyQualifiedRedirectUrl="true" maxRequestLength="100000" enableVersionHeader="false" />
<sessionState cookieName="My_SessionId" />
<httpModules>
<add name="ErrorLog" type="Elmah.ErrorLogModule, Elmah" />
<add name="ErrorMail" type="Elmah.ErrorMailModule, Elmah" />
<add name="ErrorFilter" type="Elmah.ErrorFilterModule, Elmah" />
</httpModules>
</system.web>
_Layout.cshtml:
In header
#Styles.Render("~/Content/css") #Styles.Render("~/Content/themes/base/css")
#Scripts.Render("~/bundles/modernizr")
At end of body
#Scripts.Render("~/bundles/jquery") #Scripts.Render("~/bundles/jqueryui") #Scripts.Render("~/bundles/jqueryval")
You may have a look at this article
http://codemares.blogspot.com.eg/2012/03/disable-minification-with-mvc-4-bundles.html
or you can use this simple implementation
public class NoMinifyTransform : JsMinify
{
public override void Process(BundleContext context, BundleResponse response)
{
context.EnableOptimizations = false;
var enableInstrumentation = context.EnableInstrumentation;
context.EnableInstrumentation = true;
base.Process(context, response);
context.EnableInstrumentation = enableInstrumentation;
}
}
and then when defining your script bundles in (App_Start) you can use the base Bundle class like this
IBundleTransform jsTransformer;
#if DEBUG
BundleTable.EnableOptimizations = false;
jsTransformer = new NoMinifyTransform();
#else
jstransformer = new JsMinify();
#endif
bundles.Add(new Bundle("~/TestBundle/alljs", jsTransformer)
.Include("~/Scripts/a.js")
.Include("~/Scripts/b.js")
.Include("~/Scripts/c.js"));
I'm seeing this as well in the release version. To get around it, I'm using conditional flags to achieve the same effect.
BundleTable.EnableOptimizations = true;
#if DEBUG
BundleTable.EnableOptimizations = false;
#endif
I am using the solution detailed in this SO Question. I've used this on other sites before and its worked fine, and it works on my dev box. However, when I publish to a our Windows VPS, errors return the standard IIS error page.
I have never administered a web server before, and I am not sure what settings I need to check to figure out why its not returning the custom errors I have set up. I have tried setting .net error pages for the app to off and on, with the default page set to the root site, as well as just '/'.
I have also tried setting the error pages (under iis in 7.5) to custom and detailed.
None of these seem to have any effect on the error page that is returned. What am I doing wrong here?
I remember having similar problem and I added this line to the code
protected void Application_Error()
{
var exc = Server.GetLastError();
var httpExc = exc as HttpException;
Response.Clear();
Server.ClearError();
var routeData = new RouteData();
routeData.Values["controller"] = "Error";
routeData.Values["action"] = "General";
routeData.Values["exception"] = exc;
Response.StatusCode = 500;
if (httpExc != null)
{
Response.StatusCode = httpExc.GetHttpCode();
routeData.Values["action"] = "Http404";
routeData.Values["exception"] = httpExc;
}
Response.TrySkipIisCustomErrors = true; //this fixed it
IController errorsController = new WWS_Website.Controllers.ErrorController();
var rc = new RequestContext(new HttpContextWrapper(Context), routeData);
errorsController.Execute(rc);
}
You can replace the standard IIS error pages by using the httpErrors section in the system.webServer section in your web.config file. This is in addition to the customErrors section in system.web.
<system.webServer>
...
<httpErrors errorMode="Custom" defaultResponseMode="ExecuteURL">
<remove statusCode="400" subStatusCode="-1" />
<error statusCode="400" prefixLanguageFilePath=""
path="/errors/400" responseMode="ExecuteURL" />
<remove statusCode="404" subStatusCode="13" />
<error statusCode="404" subStatusCode="13" prefixLanguageFilePath=""
path="/errors/file-upload-too-large" responseMode="Redirect" />
<remove statusCode="404" subStatusCode="-1" />
<error statusCode="404" prefixLanguageFilePath=""
path="/errors/404" responseMode="ExecuteURL" />
<remove statusCode="403" subStatusCode="-1" />
<error statusCode="403" prefixLanguageFilePath=""
path="/errors/403" responseMode="ExecuteURL" />
</httpErrors>