Mehfuz's WebLog

Live crazy, think different!

Sponsors

News

Passionate about cutting edge technologies and facinated by the modern web and phone revolution.Currently working at Telerik Corporation, the leading .net component vendor.
Follow me


Articles


Projects

August 2008 - Posts

Deploy, test and pack your code - Part 1 Using NAnt

In this part, I show a way to build and deploy your project using NAnt. As, you already might know that NAnt is a tiny deployment tool that enables you to create a deployment package with some  *.build files which contains nothing but few XML directives.

Recently, I was trying to make a deployment package for my Athena project. I generally download the latest source from server , though I have the latest source in my machine. This ensures that I have checked everything in nicely. Now, I have created a tiny build.bat file that builds the code, tests it using NUnit mocked with Typemock and makes a zip distribution of the required binaries.

Now, to make things work we first need to find dependencies, move them first to the destination folder from source , then do the build. By default build in NAnt is in release mode unless otherwise you mention anything.

<target name="build" depends="clean">
<mkdir dir="bin" />
<csc target="library" output="bin/Linq.Flickr.dll" >
    <sources>
        <include name="Linq.Flickr\Attribute\XAttributeAttribute.cs" />
        <include name="Linq.Flickr\Attribute\XElementAttribute.cs" />
        <include name="Linq.Flickr\Attribute\FlickrMethodAttribute.cs" />
          ...
          ...
        <include name="Linq.Flickr\PopularTagQuery.cs" />
    </sources>
    <references basedir="${project::get-base-directory()}\External">
        <include name="LinqExtender.dll"/>
    </references>
</csc>

As the lines says, it creates the bin folder, takes the reference from External directory , there is also a depends node which means it will fire off the taget.name = "clean" first before executing the build target. Every .build file has a root project node under which other goes.

<project name="linqFlickr" default="build" >
...
...
</project>

Here , it shows the default target is build, if not mentioned , we have to pass in the taget name to start. In build package we also need the required dlls that user need to include.

<copy todir="${project::get-base-directory()}\bin" overwrite="true">
    <fileset basedir="${project::get-base-directory()}\External">
        <include name="LinqExtender.dll"/>
    </fileset>
</copy>

Copy can have multiple file sets or it can copy a single file. Here, incase of including single (ex. readme.txt) file the following can be done

<copy todir="${project::get-base-directory()}\bin" 
file="${project::get-base-directory()}\readme.txt" overwrite="true" />

There are some static calls that you can make , that should wrap in ${ ... }. In the above script block, project:: get-base-directory() will fill the gap with current path where the script is located.Once we have built, we also need to test things out. In that case, we might have a test project that we need to build and copy the necessary dlls to the deploy folder as well. Additionally, if our test project (In my case, Linq.Flickr.Test.dll) depends a config file, then we have to copy it in a form of SomethingProject.dll.config to the deployment folder

<copy file="${project::get-base-directory()}\bin\app.config" 
tofile="${project::get-base-directory()}\bin\Linq.Flickr.Test.dll.config" />
<delete file="bin/app.config" if="${file::exists('bin/app.config')}" />

So, first you will copy the file as usual from external directory , then you will rename, NAnt will be copying to a different named file and finally delete the main file.Now, as you have two scripts ready, one for building the library and another for testing it, it is easy to combine them under one script using buildFiles directive.

<target name="run">
<nant target="build">
<buildfiles>
    <include name="LinqFlickr.build" />
    <include name="LinqFlickrTest.build" />
</buildfiles>
</nant>
</target>

This is like running tiny NAnt scripts under .build file, here I have also specified the target type, which means the target to fire up under each sub-scripts. Now, NAnt has build in NUnit task which can be done using nunit2  directive

<nunit2>
    <formatter type="Plain" />
    <test assemblyname="bin\Linq.Flickr.Test.dll" appconfig="Linq.Flickr.Test.dll.config" />
</nunit2>

But, this is not a good approach at all, if you want to use the latest version and commends. The option suitable is <exec>. Now, running tests with Typemock has two ways, one is to use the NAnt task that it supports, with the release of Typemock 5, open source project can also use it with its auto deploy option, previously it was only for commercial editions.

Steps for using Typemock with auto deploy are

  • Load the Task dll
  • start mock engine.
  • register it , usually by the open source username and license you got
  • execute it.
  • stop the mock engine.
<loadtasks assembly="${typemock.dir}\TypeMock.NAntBuild.dll" />
<typemockstart target="2.0"/>
<typemockregister company ="Typemock" license="ABC" autodeploy="true"/>
<exec program="${nunit}" failonerror="false" verbose="true" >
        <arg value="bin\Linq.Flickr.Test.dll"  />
</exec>
<typemockstop/>

Here, program="${nunit}" will extract the value from the property node under project.

<property name="nunit" value="ThirdParty\Nunit\nunit-console.exe" />

Using the current community  distribution of Typemock, there is another way to make it happen, but that will require Typemock  installed in target machine and  which is possible by the TMockRunner.exe

<exec program="${typemock}" failonerror="false" verbose="true" >
    <arg value="${nunit}" />
    <arg value="bin\Linq.Flickr.Test.dll" />
</exec>

Here, program="${typemock}" maps to

<property name="typemock" value="C:\Program Files\Typemock\Isolator\4.3\TMockRunner.exe" />

Finally, if we want to pack everything up in a zip file. we can do it in the following way.

<zip zipfile="${deployZipFileLocation}" includeemptydirs="false">  
    <fileset basedir="${targetDirectory}">  
         <include name="Linq.Flickr.dll*" />  
        <include name="LinqExtender.dll*" />
        <include name="readme.txt*" />
    </fileset>  
 </zip>              

All we need now is a batch file with NAnt command that will call the entry point script. In the end, this is just a simple one about how can we automate testing and deployment , but more complex task like sending email while a build/ test fails , incorporate workflow all can be done and with build script the possibilities are endless. NAnt works with .net compact framework and mono distribution as well. It requires no installation.

image

You need to distribute these files with your source distribution, to get user cook a binary out of the latest code (esp for open source) just by a single click. In the next part of this post, I will do the whole thing with MSBuild and show the benefits and integration factor comparing with NAnt.

You can download the skeleton script that I have supplied with LINQToFlickr project here to have a look or get a running copy from the release page.

kick it on DotNetKicks.com

Posted: Aug 30 2008, 04:16 PM by mehfuzh | with 2 comment(s) |
Filed under: , , ,
Bundle SQL script with build process using MSBuild

We are making a sample application, demo or startup kit or a toolkit with test project that requires some SQL scripts. We generally ship in a readme.txt that says it all. But hey, how about having the script under automated process , like if my SQL Server and VS 2008 is in place, with the click of Ctrl + Shift + B everything gets ready. Here, we will do just right that.

MSBuild provides a lot of community tasks that includes zip, XmlUpdater to SqlServer. You can get it all from tigris.org. After having it installed you can either copy it to your local app directory or reference it using $(MSBuildExtensionsPath). In my case I have copied the dll into the Tasks directory of my application (which is the example app supplied with LinqExtender). Anyway, there is a nice task called ExecuteDDL that will take in one or more sql script files , join with GO separator if required  and run it against your database.

To start things off I have created a Sql.Scripts.Targets. About *.Targets file, you can either include them in other targets or *.proj or *.csproj files where you will be using them. Its almost the same with NAnt scripts that terminate with .build extensions.

<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003" >
    <PropertyGroup>
        <TaskDirectory>Tasks</TaskDirectory>
        <BatchSql>Sql\script.sql</BatchSql>
       <ConnectionString>Server=localhost;Integrated Security=True</ConnectionString>      
    </PropertyGroup>

    <UsingTask AssemblyFile="$(TaskDirectory)\MSBuild.Community.Tasks.dll"
              TaskName="MSBuild.Community.Tasks.SqlServer.ExecuteDDL"/> 
</Project>

As you can see inside Sql.Scripts.Targets , I have added a block of PropertyGroup which declares the variables which I can use later in the script. I have referenced the tasks directory where the task DLL resides. Also, added the batch SQL path (can add multiple separated by ";") and the default connection string. UsingTask is just like any other using statements in your c# code that lets you include the reference of the task which you will be using in this or other files that is dependent on this.

Now, the interesting part. If you ever opened the c# project file by a notepad or any text editor, you must have seen this

<!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
       Other similar extension points exist, see Microsoft.Common.targets.
  <Target Name="BeforeBuild">
  </Target>
  <Target Name="AfterBuild">
  </Target>
-->

As it says, you can add your custom tasks under it and before or after build, it will fire up your task to do the things you want it to do. So, our final touch is to include the target file and to add the ExecuteDDL task under AfterBuild target.

With this let's un-comment the above code and add our block there.

<Import Project="Sql.Scripts.Targets" />
<Target Name="AfterBuild">
   <ExecuteDDL ConnectionString="$(ConnectionString)" Files="$(BatchSql)" ContinueOnError="false" /> 
</Target>  

That's it, next time you build the code, right after it will run the necessary scripts to setup your database.

image 

As you can see that any error occurs gives you a prompt message with VS task list window that also gives the user a clue what to do next. Finally, I have added a  hollow class library project with the scripts tied up, please download it here.

Hope that helps

kick it on DotNetKicks.com
Posted: Aug 15 2008, 02:29 AM by mehfuzh | with 2 comment(s) |
Filed under: , ,
LinqExtender 1.4 - Enhanced object tracking

Its been quite a while since I made any release of the toolkit. I basically, get into user requests, used it myself in LinqToFlickr project and came up with some new features and enhancements.

In my last post, I already mentioned about comment and photo update feature in LinqToFlickr (Athena) , where the update tracking is actually comes from this toolkit.

Book book = (from b in context
                      where b.Id == 1
                      select b).Single();

// let's update a property
book.ISBN = "1101";
// this will trigger the update.
context.SubmitChanges();

Note that Book object is a simple class that inherits QueryObjectbase for making it query enable that looks like the following with no fancy tricks.

[OriginalEntityName("book")]
class Book : QueryObjectBase
{
       [LinqVisible]// makes the property visible to toolkit
       public string Author { get; set; }
       [LinqVisible, OriginalFieldName("Bk_Title")]
       public string Title { get; set; }
       [LinqVisible]
       public string ISBN { get; set; }
       ...
       ...
}

So, during SumitChanges the toolkit will track for any changes that is made after adding or getting the item or list of items and call the Query<T>.UpdateItem

protected bool UpdateItem(Bucket item)
{ 
    Bucket contains the updated property- value map
   
    //finally do a return , if true, then only the
    //collection will be updated or 
    //it will revert back to the old one and raise an OnError event.
    return true/false;   
}

You just need to put the appropriate update logic in here. Bucket.Items contains the latest value after the user changes. Moreover, you can use bucket.Items.IsUnique or bucket.UniqueItems to track down the Identity property which is defined by UniqueIdentifierAttribute.

In addition to this , now we have another optional override Query<T>.GetItem : T . This is equivalent to the popular GetById in our database driven world.

Photo detail = (from p in context.Photos
               where photo.Id == 22212 && p.Size == PhotoSize.Medium).Single();

With this query from Athena (LinqToFlickr API), we can see that the query gets the single photo by an identity lookup and optionally it asks for medium sized photos only. Generally , we can combine it with IF-Else in the Query<T>.Process with generic search logic, but rather having two sets of logic we can also implement the GetById under GetItem override. The typical look of it

protected override T GetItem(Bucket item)
{
   T singleObject = GetItThoughUniqueValue(...);
   return singleObject;
}

Finally, AddItem, DeleteItem and UpdateItem overrides of Query<T> has now a return type bool instead of void . This forces the provider writer to return a bit status indicating success and failure of the operation. Optionally , with false status it raises a OnError event , which user can use to log the error.

There are few more updates with 1.4 release check all these out at www.codeplex.com/LinqExtender . Also, the features page gives a detailed list.

kick it on DotNetKicks.com
Posted: Aug 11 2008, 02:38 PM by mehfuzh | with 4 comment(s) |
Filed under: ,
Athena - A LINQ to flickr API (Release 1.4)

Last week, I released a new version of LINQ.flickr, which I named as Athena from release 1.4. It covers few features from flickr service, also now I have updated it with the latest LINQExtender (pre release version)  containing updated Object Tracking Service (OTS) that will enable it to update photos and comments as if like LINQ to SQL.

First of the interesting features that most others asked me to implement is the Extras support, with this you can get additional information about your photos by querying with Extras enum.

var query = (from photo in context.Photos
            where photo.SearchText == "Redmond" && p.Extras == (ExtrasOption.Views 
| ExtrasOption.Date_Taken | ExtrasOption.Date_Upload)
            select photo).Skip(0).Take(10);

This will return 10 photos contains word "Redmond", additionally it will have Photos.Views , Photos.TakeOn and Photo.UploadedOn that user might find useful. The extras options is provided by flickr and it has options like GEO, tags , etc.

Athena , now covers two new endpoints.

flickr.photos.setMeta and flickr.photos.comments.editcomment.

Comment comment = (from c in context.Photos.Comments
where c.Id == "1234"
select c).Single();
 
comment.Text = "This is a updated comment.";
coment.SubmitChanges();

This will update the comment for me. Notice that it tracks the object for update and automatically fires the appropriate method to do the update. It comes as  a part of enhanced LinqExtender  OTS which I will describe a bit more in other post about how to implement it.

Finally, the easy authentication method that I already described in my previous post, take a look at that as well. Also, the coming update will have photo set support and watch out for that as well. There are few new development updates like one click test and deployment package creation with NAnt that lets me update my app with the latest source without running IDE and test program. There are also a lot of re-factors and performance enhancements that makes the API more stable.

That's it. Enjoy and file me bugs!!

kick it on DotNetKicks.com

More Posts