Tuesday, September 28, 2010

Installing Redmine on Windows

Redmine is an excellent project/issue/bug tracking tool. As of this writing, V1.0.1 is just released. I guess V2 is going to be based on RoR V3.

Most of the installation is just no brainer, following the directions in their website. I used a MySql and setup a initial DB is also very easy, though I did have to follow the installation instruction to download the MySql Dll.

Now you should be able to start the application from command line. But wait, normally you should use mongrel or webrick as your webserver. A "gem install mongrel" will do the trick. And further, you might want to run your website as a service, following most of the advices to run mongrel as a windows service will require you build a native dll. I don't want to install cygwin or gcc to just compile those stupid dlls. Therefore I followed the advice in Redmine's website. Actually if you download the Win 2003 Res Kit, you can find the directions also in help on topic srvany.exe.

Another bloody experience, which took me 3 hours to figure out was, don't run the service under LocalSystem account, which will prevent network access. It seems this will block subversion access!

Integrating SVN to Redmine can be a little tricky.
1. You need the svn.exe file on system path. Don't forget to re-open a cmd window after you have changed the system path.
2. If you use https protocol, another trick is, you have to run below command to accept the certificate (permanantly) from the server, then everything will be fine.
3. And if you specify any special user rights to your repository, don't forget to grant at least read-only access to the user you specified in Redmine.
4. If you are integrating to a repository with huge history, the intial importing can take a long time.

Authenticating using Active Directory is also a little tricky. You can use this image as a reference.

Monday, August 9, 2010

TDD, it's not about testing.

I subscribed a lot of blogs and it seems in their world, TDD is something that needs not to explain, at least the name it self is as clear as the name of "Unix". But sadly I discovered this might only be true in some software house, but not in most of the IT departments in normal companies.

Anyway, I found some good explanation about TDD, which is very insightful. TDD is not about testing, it's about design. The tests to guarantee quality, to weave the safe-net is a valuable byproduct.

I recall one of the API for a report generator. The report format looks complex. I decided to design a model for the report, and once the model is done, generating the report should be straight forward. I started with some tests to generate part of the data the report needs, this forced me to think about the model structure and API in another angle. And finally it turned out a very different, if not completely different, but simple API. I reviewed it and was glad about its elegance. I would not be able to design such a nice API if I test after!

Sunday, August 1, 2010

Setting up Git server using Apache on Windows

Update: Gitblit is a better choice!

I posted an article to setup a Git server on windows using MSysGit, with Git's native transport protocol. Though it works good, the setup of SSH server and client is not a easy cake to some. Git's HTTP support on Windows was known to be less efficient. But given today's hardware and especially if you are using it in an enterprise environment, this can hardly be a problem than the complex setup process of SSH ways. Recently I found a way of creating Git server using Apache and it's both simple and comprehensive. So take a look.

Friday, May 28, 2010

Great FitNesse tutorial!

I was attracted by FitNesse recently and found this great tutorial from Brett who is working with uncle bob at ObjectMentor.

The tutorial is great since it not only introduced the concept, but also a really good example to guide you through the door. Meanwhile, without bending rules by ugly codes.

Is public field still so evil in C#?

In Java, there is a rule: "never make your field public". This rule is borrowed by C# when a lot of Java programmers jumped to .NET. I'm one of them and I loyally kept that habit, you will find no public field defined in classes from my hand. While, not exactly. That changed recently.

One of the main reason of "keep fields private" in Java was, field accessors and method calls are very different. If you expose your field as public, then all dependent applications will use obj.fieldName to access it; while if you encapsulate it using a access method, it's like obj.getField(). So if you have make the field public, and then you need to introduce some business logic on the field, then you've got a headache: you need to change all the depending source codes. With IDEs like IDEA and Eclipse, this kind of change can be much easier and robust than before, but still it's going to take effort, which is a waste.

Since the first day of C#'s birth, it has a special language feature, Property, which I believe was borrowed by the success of Delphi. By this feature, a field can be encapsulated by a property and accessed in the same syntax as field, except under the hood, it's really a method call, and if you disassembly the IL code, there is really setField and getField methods generated. So in this case, is it still so evil to mark your field private and provide a property for it? In most of my applications (and I believe in most of most programmers' applications) the property is nothing but just a dummy get/set pair. And to make this pain less painful, MS invented the "auto-property". But the question is, is this encapsulate really necessary?

I don't think so! For C# applications, the "private-field-rule" is not applicable any more. Since if you want to change a field to a property, none of the dependent codes should change (unless if you use reflection). The only thing a field can not do is, it can not be marked as virtual while properties can; and fields can not be put into interfaces while properties can be (you can make a property writeonly and not field, might be useful for setting injection by IoC). So if you need to make a NHibernate friendly entity, or if you need to define interfaces to other module, use property. For most of rest, try to use field, until you find the needs to introduce property. This will help you get code clean.

Friday, May 14, 2010

Content types if you deploy ClickOnce applications with non-IIS web server.

Found below info from MSDN. BTW, mongoose is a very good candidate for this...

File name extension

Content type

.application

application/x-ms-application

.manifest

application/x-ms-manifest

.deploy

application/octet-stream

Wednesday, May 12, 2010

Using Teamcity to build(publish) .net application

Since .NET 2, there is a nice feature to "publish" your application, called ClickOnce, to a website, file share or to CD/DVD. If your application only contains managed code (MS termed this smartclient), this feature is a easy way to simplify the deployment of the application and keep your users update date. I happen to have such a application with a group of users up to ~50 distributed from Europe to Asia, so deployment always bothers me. To make things worse (or better:), I follow the agile way of development. That means frequent change/deployment of software. If it is a website, there won't be a problem, but I'm still stuck to desktop and I need an easy way to handle this. Luckily there is a built in function named "publish" in VS2005 (the aged IDE I'm using), which can make a simple html page and some xml files so you can put them on a website and the users can just click the page and start the application. This only works for IE, unfortunately if you can only use .NET2. Since .NET 3.5, there is a Firefox plugin from MS, and there has always been a unofficial Firefox plugin, but I never tried. Anyway it's enough in my case. One thing to notice is, the application is not downloaded for every startup. The timestamp is used to check if there is a new version on server, and if the return value is 304, http-not-changed, then the copy from IE's local cache is used , deployment file (.application) is downloaded and the version embeded in is compared to the version installed in the local application cache. If the version on server is newer, then the application is downloaded again, or the local copy is used. So this suits local network perfectly, unless your deployment is too large (>10MB?). And it seems the application is running in a full trusted mode, with user's confirmation through a dialog showing the publisher can not be verified (maybe a valid certification key would even remove this dialog, I did not tried).

BTW, it's better to use the context menu "Publish..." in project explorer. I've read/experienced unstable publish when using the "publish wizard"/"publish now" button in the publish tab of project properties page.

I have a build server using Teamcity and each time there is a change in my source code, it will grab it and build the software, and notify some colleagues to deploy it. The tool has great web gui and is free if you limit your project to 20 and users to 20. With some money, you can get more "enterprise" features like active directory integration, etc.

I have been using the build server to build "normal" projects (with out "publish") for quite a while and it all worked fine, until I added publish as one of the targets. The actual build still runs well, but there was a wired error occurred when the publish target is running:
warning MSB3155: Item 'Microsoft.Net.Framework.2.0' could not be located in
I searched through the net and found some solutions. But it does not fit all my situation. I could not find the folder specified in the article and copy the whole folder is a little overkill. In my case (VS2005+.NET 2.0), the folder is under
%ProgramFiles%\Microsoft Visual Studio 8\SDK\v2.0
So the register key
sdkInstallRootv2.0 under HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework
should point to this folder and I did not copy everything, only the "BootStrapper\Engine" folder, and the "signtool.exe" under the "bin" folder (keep the bin folder). Since the signtool.exe needs capicom.dll, I copied it from %ProgramFiles%\Microsoft CAPICOM 2.1.0.2\Lib\X86. Then build again and bingo, it worked!