MSBuild parse item metadata - msbuild

Is there anyway to modify each item in an item group? For example, given this item:
<_CustomAreas Include="..\My.Project.*\Areas\**\*.*" Condition="'$(AppBuildFolder)' == ''" />
I want to remove the "..\My.Product.* portion. Basically we have separate project containing MVC areas, and in the Package / Deployment (MSDeploy) we want to copy them into the main project. Here's where the group is used:
<FilesForPackagingFromProject Include="%(_CustomAreas.Identity)">
<DestinationRelativePath>Areas\%(relativedir)%(Filename)%(Extension)</DestinationRelativePath>
</FilesForPackagingFromProject>
$(relativedir) is coming through as "..\My.Project.Plugin1\Areas**." and it ends up in the package as ZipFileRoot\My.Project.Plugin1\Areas (The .. backs out of the hardcoded Areas, and then it just creates the folder for the plugin\areas) where I'd like it to actually all end up in ZipFileRoot\Areas.
Thanks
Andy

The RegexReplace (credentials: guest/guest) task should be able to match \My.Product.* and replace with an empty string.
Something like this should work: (untested, need to verify escaping)
<RegexReplace Input="%(_CustomAreas)" Expression="\\My\.Product\..*" Replacement="" Count="-1">
<Output ItemName="_CustomAreas" TaskParameter="Output" />
</RegexReplace>
There's a little work getting the MSBuild Community Tasks up and running, but enough good stuff in there for me to find it worth the effort.

With MsBuild 4.0 You can use String methods directly in your script (or use inline tasks). With this option, you can edit your relativedir to delete the My.Project.* part .
You can see examples in this article : http://sedodream.com/2010/03/07/MSBuild40PropertyFunctionsPart1.aspx

Items in ItemGroups can have an Exclude attribute that allows you to specify items to leave out.

Related

Timestamp of builds in Teamcity API

I am trying to get data of my builds from Teamcity and place it into a dashboard I am creating. I am getting most of the data but this thing I am missing is the timestamp of the builds. I have searched alot on internet but cant find it. In teamcity I can see the timestamp of all the builds but it is not available in the timstamp.
All suggestions are appriciated.
Thanks
You don't need to make additional calls for each build, but you need to craft how you want the response returned. There's a query string parameter called fields that lets you define what you want to bring back.
e.g. to return the start and finish data in your original call you can add &fields=build(startDate,finishDate) to your original request
/httpAuth/app/rest/buildTypes/id:##BUILD_TYPE_ID##/builds?fields=build(startDate,finishDate)
This would return something like this
<builds>
<build>
<startDate>20140202T230456+0000</startDate>
<finishDate>20140202T230518+0000</finishDate>
</build>
<build>
<startDate>20140202T224912+0000</startDate>
<finishDate>20140202T224957+0000</finishDate>
</build>
</builds>
The caveat to this is that you now have to exclusively define what you want returned. So to return all the other fields and the start / finish date, add this parameter to the query string
&fields=build(id,buildTypeId,number,status,state,branchName,defaultBranch,href,webUrl,buildTypeId,startDate,finishDate)
TeamCity documentation - Full and Partial responses
Hope this helps
After you GET /app/rest/builds?locator=buildType:..., you need to get the detailed data of all the individual build runs you're interested in. That, unfortunately, means an extra REST call for every individual build.
The URL for each build will be in the form /app/rest/builds/id:21966, but don't hard-code this in your program. Instead, as you loop through all the builds (returned by your first call), take each build's href attribute and GET that.
To summarise:
* GET /app/rest/builds?locator=buildType:... once
* for each build in the returned data set, take its href and make another REST call
* for each returned build detail, the timestamps are in the following sub-elements: queuedDate, startDate, finishDate, triggered
We've tried implementing a dashboard this way before but found it unacceptably slow (too many REST calls). There is an alternative, which is to write a TC plugin (use the native OpenAPI): that will be much faster but of course it's more work.

WiX: How to create file name from a property value

I have a working WiX installer that correctly writes properties to certain INI files, which works fine, but I have a need to generate the name of an INI file on the fly, from the computer name, eg.
MACHINE(xxx).INI
where xxx is my computer name.
I have tried all sorts of combinations of properties and I just can't seem to get it working. Can anyone put me right ?
This is my latest attempt that doesn't work:
<Property Id="MACHINEINI" Value="MACHINE([%COMPUTERNAME]).ini" />
...
<IniFile Id="IniPermissions"
Directory="MYDIR"
Action="addLine"
Name="[MACHINEINI]"
Section="[ComputerName]"
Key="Permissions"
Value="TEST" />
I never see the value of MACHINEINI, as the filename that gets created is actually called
[MACHINEINI]
The value it writes in is correct, so I see the contents as follows:
[xxx] Permissions=TEST
(where xxx is my machine name)
I have tried using [ComputerName], [COMPUTERNAME], [%COMPUTERNAME]
When I build the installer, I get the following error:
C:\Source\blah\BLAH.wxs(50) : warning CNDL1077 : The 'MACHINEINI' Pro
perty contains '[COMPUTERNAME]' in its value which is an illegal
reference to an other property. If this value is a string literal,
not a property reference, pl ease ignore this warning. To set a
property with the value of another property, use a CustomAction with
Property and Value attributes.
The underlying Windows Installer table doesn't support this. Note that the FileName column is of type FileName. Only the Formatted type can take a [PROPERTY].
IniFile Table
You could need a custom action to write temporary records to the IniFile table to transform the file name. The advantage versus using a custom action to literally write the INI file is that rollback would be automatically handled for you.
It's not possible to tell you how to do this exactly since I don't know what language you'd want to use to write the custom action.
A simpler approach (from the installers perspective) would be to transform the [KEY] name inside a single INI instead of writing to different INI files.

Output tag - TaskParameter and PropertyName, ItemName - what do this two include?

The msbuild contains output tag. It has avialable attributes: TaskParameter and PropertyName, ItemName.
How they can be used? What are they containing?
Please, can you help me to understand and give an example? For example you can use xmlpeek task with output tag inside.
(I read documentation on msdn but I still don't get it. :( )
The question has been answered, but I will follow up with an example.
In the MSBuild community task Time, an output parameter Month can be set to a property called
CurrentMonth as follows:
<Time>
<Output TaskParameter="Month" PropertyName="CurrentMonth" />
</Time>
In the MSBuild Community task time source code the property Month inside the Time class looks like this:
[Output]
public string Month
{
get { return month; }
}
All properties mapped with an [Output] attribute can be set as a task parameter and
assigned a MSBuild property name as specified above.
To read more about the Time task, a CHM file is available in the MSI file available at the following URL: http://msbuildtasks.tigris.org/
These are a way of passing values back from the task to the MSBuild script. It is basically a way of mapping a property in the compiled task code that has been decorated with the [Output] attribute back to a property in your MSBuild file. This page gives you more details about it: MSDN: Output Element (MSBuild). This article also has a good example of it in action: How to auto-increment assembly version using a custom MSBuild task

MSbuild built in variables

Could someone translate this, into a syntax that uses the built in variables?
\\myserver\builds\mybuild\Daily_20090525.1\Release\_PublishedWebsites\myWebsite
it should be something like:
$(DropLocation)\mybuild\$(?...)\Release\_PublishedWebsites\myWebsite
This might help:
substitute "mybuild\$(?...)" with "$(BuildNumber)"
I had a similar problem where I was trying to copy from the drop location to a "Latest" folder. I found that to construct the final destination of the files (\MyServer\MyShare\builds\MyBuild\Daily_20090708.14\Mixed Platforms\Release) translated to the following using variables:
$(DropLocation)\$(BuildNumber)\%(ConfigurationToBuild.PlatformToBuild)\%(ConfigurationToBuild.FlavorToBuild)
I also found it helpful to use the Message task for troubleshooting. The following task will tell you what the variable translate to.
<Message Text="$(DropLocation)\$(BuildNumber)\%(ConfigurationToBuild.PlatformToBuild)\%(ConfigurationToBuild.FlavorToBuild)\"/>
To see the output, look in BuildLog.txt.
PS: My tasks that used the properties and items mentioned above where located inside <Target Name="AfterDropBuild">.

Output the name of the current DLL being acted on using MSBuild

This is probably a really stupid MSBuild question but if I have
<ItemGroup>
<Dll Include="<Path_to_DLLs>\*.dll" />
</ItemGroup>
And then
<SomeTarget useFiles=#(Dll)>
....do stuff
</someTarget>
What I want to do is to output the current item that #(Dll) is looping through. Basically I wanting to output the name of the current DLL being acted on.
I think this must be possible and it is probably so simple but it is driving me nuts!
Aha The joys of metadata.
On the creation of every item in MSBuild, specific MetaData is assigned to it.
In this case I could use %(Filename) to retrieve the file name
This is a full list of Well Known metaData