Developerdave
Craftsmanship over execution
Craftsmanship over execution
Apr 1st
I am working on a project at the moment which needs some source control. Which project doesn’t after all, I need remote access to this project so my local git repositories weren’t going to work.
I stumbled across this free git repository ProjectLocker, they support both SubVersion and Git and it is free for up three projects and 300Mb. Luckily the project I am working on isn’t that big so I went ahead and signed up.
I’m not going to go into how to use Git etc, etc. Just let you know about a little gotcha. When you try and upload your first piece of source code you may receive a permission denied error. It will hint that your password is incorrect by keep on asking you for the password again and again. It will be because you haven’t added a public key. Thanks to the blog article by Ben Bahrenburg for this http://blog.bahrenburgs.com/2010/01/using-git-with-projectlocker-on-mac.html
Oct 19th
Today I needed to perform a diff between two branches in SubVersion. I had to look this up in the documentation so decided to share:
There are two main ways of performing the diff.
This example will summarise the changes between the trunk and the release branch. If you want to see the actual changes then leave the –summarize option off the command.
This example will summarise the changes between two revisions of code (these revisions can be in different branches). To find the latest revision number of branch you may find the following code useful.
Oct 15th
I decided to automate the running of the Microsoft’s SEO Toolkit at work to integrate with our automated build system. I quickly hit a problem getting the SEO Toolkit to authenticate through a proxy server. The reports all came back with the following error “407 proxy authentication required”
I found that you can make the SEO Toolkit use a proxy server by doing the following:
Sep 21st
I recently held a coding dojo to in investigate feasibility of following Uncle Bob’s Three Rules of TDD within C# and JavaScript. We decided to go for a simple problem so followed the bowling kata the results and observations of the dojo are included below:
A minute ago all their code worked! And it doesn’t matter who you pick, and it doesn’t matter when you pick. A minute ago all their code worked!
Sep 20th
I’m currently reading Continuous Delivery: Reliable Software Releases through Build, Test, and Deployment Automation by Jez Humble and David Farley.
These are some of my thoughts on chapter 1:
Antipattern: Deploying Software Manually
Many organisations release software manually. By this we mean that the steps required to deploy such an application are treated as separate and atomic, each performed by an individual or team. Judgements must be made within these steps, leaving them prone to human error.
This is true of many organisations and makes release days stressful ones often with early starts and lots of anxious release personnel, developers, testers and business people. There is an over reliance on manual testing to confirm that the application is running correctly, frequent changes to release process during the release to account for differences in environment. It is common for releases to take an hour and even longer to rollback!
Instead…
Over time, deployments should tend towards being fully automated. There should be two tasks for a human being to perform to deploy software into a development, test, or production environment: to pick the version and environment and to press the “deploy” button. Releasing packaged software should involve a single automated process that creates the installer.
I couldn’t agree more and this is something that is needed within many organisations, getting all the teams to work successfully together and collobrate towards this goal is often a challenge but one I feel you should take on.
We have heard it said that a manual process is more auditable than an automated one. We are completely baffled by this statement. With a manual process, there is no guarantee that the documentation has been followed. Only a automated process is fully auditable. What is more auditable than a working deployment script?
We are human afterall even if there is a documented process when we do something manually we will adapt the process to make it work and we may or may not keep the documentation up to date, most the time not!
Antipattern: Deploying to a Production-like Environment Only after Deployment Is Complete
It is all too common for the first time that a software product is deployed to a production-like environment is once we have got to what we think is a releasable state. This causes significant overhead and handing over to operations teams to get the system released into production and supported – it shouldn’t be like this and it doesn’t have to be.
Once the application is deployed into staging, it is common for new bugs to be found. Unfortunately, there is often no time to fix them all because the deadline is fast approaching and, at this stage of the project, deferring the release date is unacceptable. So the most critical bugs are hurriedly patched up, and a list of known defects is stored by the project manager for safekeeping, to be deprioritised when work begins on the next release.
Antipattern: Manual Configuration of Production Environments
It is typical that all of the different concerns of deploying software are owned and managed by different teams for example, database connection settings, network settings, etc, etc. Configuration is often performed manually by the different teams. Instead you should aim to manage this configuration using scripts and these scripts should be automated and under source control. One difficulty of this may be the security permissions of sensitive operations for example firewall settings and these departments need to closely monitor changes and do things the way they always have, manually.
Every change should trigger the feedback process
Imagine if the whole of your release process was automated and took seconds to perform and could be done repeatedly again and again at the touch of a button and the testing fully automated.
Sep 4th
In MVC there are numerous ways to pass data from your View to Controller, the most common is through view data and view model. Say for example you had a simple Employee model and EmployeesController action as shown below:
As long as the form fields have fields for the same field in the name property it will be bound to the Employee object automatically. It’s not the only way to pass data though you can post data from the View to Controllers via form parameters, querystring, route parameters, etc, etc. Model Binders are responsible for binding a model to this data. All model binders implement IModelBinder either directly or indirectly. The following model binders are available:
The default binder, DefaultModelBinder and is used whenever you haven’t explicitly set another type of binder. The IModelBinder interface looks like this …
Most of the time there is no need to write a custom model binder, but on a project I’m working on at the moment there was a requirement to do just that. Say for example in the Employee object there was a field which held training course codes that the employee had been on as a string array. In the View we have a simple field for the training course and an Add button when you click Add it adds the training course you have entered and puts a label under the textbox showing what you have just entered and you are free to enter another training course code. The name property of the fields are as follows trainingCourseCode-1, each time you add a course the number increments so if you have four courses the following fields would be on the form trainingCourseCode-1, trainingCourseCode-2, trainingCourseCode3 and trainingCourseCode4.
This isn’t going to map automatically using the default model binder so one way of tackling this is to use a custom model binder.
All that is left to do now is let the MVC framework that we wish to use the EmployeeModelBinder to bind Employee objects, this is done in the Global.acsx file like this.
Sep 3rd
The ASP.NET Routing module is responsible for mapping incoming browser requests to controller actions. When you create a new ASP.NET MVC application, the application is configured with some standard routes in the Global.ascx file. The route table is created during the Application Start event of the Global.ascx file.
Line 2: tells MVC to ignore any requests to .axd files and not route them to an MVC controller.
Line 3-11: adds a default route which maps to a URL which matches the format:
/Details/Index/3
The default route maps this URL to the following parameters:
controller = Details
Action = Index
ID =3
Line 8-9: sets some defaults for the controller and action, so if we type a url such as http://my-site.co.uk/ it would automatically map to the Home controller’s Index action.
Line 10: specifies that the id field is optional.
The example below shows the corresponding Index method of the DetailsController this method is invoked by the URL /Details/Index/3 and /Details/Index
Default routes are all well and good but what if we want something not default? Well out of the box the routing in MVC is clever enough to route URLs with query string parameters on, so for example:
| URL | Maps to |
|---|---|
| /Search/ | Index |
| /Search/Results?query=iphone | Results |
The first URL /Search/ we already understand how this maps from the previous examples but the second URL /Search/Results?query=iphoneis more interesting. This values can be read from the query string just like they could be in normal ASP.NET, whilst there is nothing wrong with this URL we can make it better. What if you wanted to use the following URLs?
| URL | Maps to |
|---|---|
| /Search/ | Index |
| /Search/IPhone | Results |
| /Search/IPhone/2 | Results |
We can enable these URLs by adding some additional routes into the Global.ascx file
You must add this new route above the default otherwise the default route will be mapped and you will end up in the wrong place. The route is not that different to the default one, instead of using {controller} to specify that the URL specifies the controller we want instead the URL starts with /Search/ but instead goes to the Search Controllers Results action. Line 10: indicates that the page is optional so in the case no page is specified it is defaulted to 1 otherwise the value passed.
The Action method for this route would look like the following:
Sep 1st
You sometimes come across situations in which you need to install a ruby gem which is located on your machine. This happens frequently in work as we are behind a firewall and it can often lead to strange errors despite specifying the proxy server in the ‘gem install’ command.
For purposes of demonstration I am assuming that you want to install the rspec gem which you have downloaded from the following site: http://rubyforge.org/frs/?group_id=797. Once you have the gem on your machine, open a command prompt where you have downloaded the gem to and run this command
If you get an error saying gem-name-x.x.x needs some-other-gem then you will need to download these gem files as well and download them first. For example rspec-1.3.0 has the following dependencies.
Assuming you have downloaded all of the dependencies and installed one by one then you will now be able to install rspec.
Aug 12th
I’ve tried lots of things for sharing and posting code and none have really worked the way I would like. I recently tried Gist …
Gist is a simple way to share snippets and pastes with others. All gists are git repositories, so they are automatically versioned, forkable and usable as a git repository.
Jul 28th
For a project I am currently working on I have been trying to set a hidden field value using Selenium. This proved more difficult than I thought so I thought I would share how to do it. I decided to use Javascript to set the hidden field value, using Selenium you can run a script using the RunScript command.
To get access to the hidden field you have to prefix document.getElementById(...) with this.browserbot.getCurrentWindow() I was then able to successfully set a hidden field from within an automated acceptance test.
The reason for this is because by default the code snippet wil run in the runner’s test window, not in the window of your application.