I went on a BBQ this weekend and baked a cheesecake for the event. I took a look at a couple recipe's online then went crazy and just sort of whipped up something on my own I thought would be good and it turned out to be tremendous so I thought I would share it with our engineering community here in case anyone also has a sweet tooth for a cheesecake. So good it tastes like a million bucks!
Ingredients:
1.5 cups of sugar
1 teaspoon vanilla
3 8oz packages of cream cheese
3 eggs
4 oz heavy whipping cream
1 cup of dark chocolate chips
1 lb chocolate chip cookie dough
3 6oz packages of fresh raspberries
1 package of gelatin (optional)
Directions: Preheat oven to 350.
The Crust
In a greased 9" springform pan ($10 at local wal-mart) take your 1lb of cookie dough and using your hand smash it flat into the bottom of the pan, spread evenly. Place it in the oven at 350 for 15 minutes. The cookie dough will be still gooey when it comes out and this is OK. Let it cool for 30 minutes, or put it in the fridge to cool for 15.
The Filling
In a mixing bowl add 1 cup of sugar and the 3 packages of cream cheese. Stir together while adding 1 egg at a time making sure each egg is stirred well into the cream cheese before adding the next one. Add the vanilla and heavy cream and continue to stir until it starts looking lusciously smooth.
The Topping
Add 12oz of raspberries (2 of the 3 packages) to a blender with the remaining 1/2 cup of sugar and liquefy into a puree.
Optional
You can mix up a packet of plain gelatin in 1 cup boiling water and put 1/2 in the cheescake batter and 1/2 in the raspberry puree. It helps makes the cheesecake more firm.
Assembly
Pour 1/2 of the creamcheese batter into the springform pan. Then add the 1 cup of dark chocolate chocolate chips spread around pretty good. Then add the remaining creamcheese over the chips.
Pour some of the raspberry topping on top of the cheesecake. Not too much, perhaps 1/4 cup, dripping around the top of the cheesecake and use a knife or something to swirl it into the top of the cheesecake (a chopstick or skewer works well too).
Put the rest of the raspberry puree sauce into a bowl or plastic container and throw it in the fridge to chill.
Pop the cheesecake in the oven at 350 for 60 minutes. After you take it out run a knife around the edges and then let it cool for at least an hour. Place the cheesecake in the fridge and let it cool for at least 4 hours.
Serving
To serve the cheesecake take it out of the springform pan and remove it from bottom plate using a plastic spatula (so as not to damage the pan) it should pop right off but be careful and work around the edges. Put the cheesecake on a serving dish and ring the remaning packet of raspberries around the cheesecake.
Take out the remaining raspberry puree sauce and when you plate a slice of cheesecake put 1-2 spoonfools of puree on top and 1-2 more around the cheesecake.
Conclusions
Deliciousness...fattening too, but totally worth it :) the special thing is the cookie dough crust which really makes it one of the best deserts ever.
Sorry no pictures, the cheesecake was eaten before I thought to blog about it. But it would look something like this except with raspberries.
Tuesday, June 23, 2009
Friday, June 12, 2009
Parallel Development With Plastic SCM
Over the years I have worked with many SCM tools and they all say they support parallel development but they all do it in very different ways with all kinds of strategies and best practices that vary not only from system to system but also from situation to situation. This is one of the reasons why the Appleton/Berczuk book on branching patterns is so important, so that SCM admins can determine how best to implement a branching strategy to support their ideal development needs in the given enviroment.
With that in mind I've put together a 30 minute video to detail how we recommend doing things with Plastic. The first 15 minute talks in general about parallel development and what some of the pro's and con's are while the second 15 minutes is an example demonstrate of how we recommend using Plastic SCM to implement a simple yet effective parallel development environment. I focus on workflow and best practices while also incorporating some additional useful tools like CruiseControl, NUnit, TestComplete and Jira to help facilitate the process.
Here is the agenda for the video:
Link to video: http://www.plasticscm.com/demos/paralleldevmovie/Bparalleldev.htm
Link to PPT: http://www.plasticscm.com/demos/paralleldevmovie/BetterDevThroughBranching.ppt
With that in mind I've put together a 30 minute video to detail how we recommend doing things with Plastic. The first 15 minute talks in general about parallel development and what some of the pro's and con's are while the second 15 minutes is an example demonstrate of how we recommend using Plastic SCM to implement a simple yet effective parallel development environment. I focus on workflow and best practices while also incorporating some additional useful tools like CruiseControl, NUnit, TestComplete and Jira to help facilitate the process.
Here is the agenda for the video:
- Define the problems of serial development
- Benefits of parallel versus serial development
- Problems with parallel development
- How to eliminate or lessen the problems
- Keys to effectiveness
- Demonstration of key points in action
Link to video: http://www.plasticscm.com/demos/paralleldevmovie/Bparalleldev.htm
Link to PPT: http://www.plasticscm.com/demos/paralleldevmovie/BetterDevThroughBranching.ppt
Monday, June 08, 2009
Personas for Plastic: dress up your SCM!
Well, not yet downloaded from the real "personas" website, but the upcoming Plastic SCM 2.8 will let you customize the banner so it can better reflect your "hacking mode".

So, if you and your colleagues feel that you're working on "skunk works" mode, why not customize your Plastic SCM GUI accordingly? The same holds true for whatever graffiti, terminator, matrix and whatever other themes you come up with... :-)
Enjoy
So, if you and your colleagues feel that you're working on "skunk works" mode, why not customize your Plastic SCM GUI accordingly? The same holds true for whatever graffiti, terminator, matrix and whatever other themes you come up with... :-)
Enjoy
Labels:
news
Wednesday, May 06, 2009
Plastic SCM & PowerBuilder installation guide
This post describes how to configure PowerBuilder environment to use Plastic SCM as the source code control provider. It assumes the Plastic SCM SCC Plug-in is installed and that your client machine can communicate with the Plastic SCM server.
From Plastic SCM side
You have to change the Plastic SCM preferences before start working with PowerBuilder. You must go to Plastic preferences, then click in the "Other options" tab, and enable the option:
Compare file contents instead of using timestamp for 'quick diff'.
From PowerBuilder side
In order to bind a PowerBuilder workspace with a Plastic SCM one, you must rigth click on the PowerBuilder workspace and then on properties menu option. Then, select the tab "Source control" and you will see a screen like the following one. Select Plastic PLUGIN as Source Control System.
Also you must enable the following options:
Perform diff on status update
Supress prompts to overwrite read-only files
You must add the following parameter in the Library section:
SccMaxArraySize=X, being X the number of files per SCC call. A good value could be 5000.

Now Plastic SCM and PowerBuilder are configured to start working. You can take a look at the PowerBuilder documentation about SCC tasks here
From Plastic SCM side
You have to change the Plastic SCM preferences before start working with PowerBuilder. You must go to Plastic preferences, then click in the "Other options" tab, and enable the option:
Compare file contents instead of using timestamp for 'quick diff'.
In order to bind a PowerBuilder workspace with a Plastic SCM one, you must rigth click on the PowerBuilder workspace and then on properties menu option. Then, select the tab "Source control" and you will see a screen like the following one. Select Plastic PLUGIN as Source Control System.
Also you must enable the following options:
Perform diff on status update
Supress prompts to overwrite read-only files
Performance considerations
By default PowerBuilder calls to the SCC provider with file packages. The default value is 25, so if you want to checkin 100 files, PowerBuilder will call the SCC provider 4 times, and will create 4 different changesets.This is a behavior that we want to avoid, due to our checkin operation being atomic. This value can be changed in the PowerBuilder configuration file (pb.ini), that is placed in the PowerBuilder root installation folder, by default:
c:\Program Files\Sybase\PowerBuilder\pb.iniYou must add the following parameter in the Library section:
SccMaxArraySize=X, being X the number of files per SCC call. A good value could be 5000.
Now Plastic SCM and PowerBuilder are configured to start working. You can take a look at the PowerBuilder documentation about SCC tasks here
Friday, May 01, 2009
Self documented development through inch-pebble checkins
Developers hate writing documentation. But when you find a weird bug or need to understand why a certain change was done, then you wish you had proper documentation. The problem seems hard to solve. Good comments can help and techniques like diff debugging and proper code review tools can help too. But what every developer does on a regular basis is checking in code to his repository. What if the way in which you check in could help self documenting the code?
Side note: I find the technique I describe here not only good for self documenting changes but also to capture the way in which lead programmers work in such a way it can be used to teach the newcomers...
Read more...
Side note: I find the technique I describe here not only good for self documenting changes but also to capture the way in which lead programmers work in such a way it can be used to teach the newcomers...
Read more...
Labels:
best practices
Thursday, April 09, 2009
Finding who’s to blame – Plastic SCM annotate
One of the less known features in Plastic SCM is its ability to track changes on a line basis using the blame (or annotate) command.
I’m going to explain how to use the cm blame | cm annotate command (actually blame and annotate are aliases to the same cm command), and how it can help you identifying changes.
Let’s start with a very simple file with a few lines of code like the one below.

And then let’s start making changes in the main branch and in two new more branches, until we’ve a tree like the one at the following image.

At any given point in time we can run a blame command to a given file and identify where the changes came from. Let’s see how Plastic SCM can identify it looking at the next diagram.

What Plastic does is climb the version tree upwards from the starting point you’ve at your workspace. If you start up at revision 1 on /main, changes will only come from this revision itself or the one immediately up. Something different will be displayed if you start from rev 2 at /main/task001.

The good thing is that the Plastic annotate/blame command is not only restricted to climbing the tree up through the branch, but it can also go through the other branches as soon as there are available paths (created when you merge branches), so properly identifying where changes come from.

After merging the two branches, the new revision 3 at /main, will have contributors not only from its previous revs on the branch, but from the other branches. The interesting point to highlight is that changes are not identified as coming from revs 2 and 3, but from the correct ones in the branches.
Considering Plastic SCM promotes using branches as much as possible, and linking branches to tasks/issues/defects on your favorite project management/issue tracking system, you’ll be able to track where exactly changes came from.
Let’s now go through a step by step example, using the command line, to explain how annotate behaves in a real scenario.
Let's create a couple of smart branches from the CLI
And now make a change on the main branch.
I'll be using a co/ci cycle, but as you'll see below, you can follow a commit-only cycle with Plastic too.
Now switch to task001.
And now I'll show a ci only cycle
Now onto task002
Let's go back to br:/main and run the annotate before merging.
And now on the branches:
Let's merge the branches back to main:
And blame:
Second branch:
How does the vtree look?

And finally a graphic explaining the annotate I just showed above.

It's also possible to decorate each line with the comment:
Enjoy!
I’m going to explain how to use the cm blame | cm annotate command (actually blame and annotate are aliases to the same cm command), and how it can help you identifying changes.
Let’s start with a very simple file with a few lines of code like the one below.
And then let’s start making changes in the main branch and in two new more branches, until we’ve a tree like the one at the following image.
At any given point in time we can run a blame command to a given file and identify where the changes came from. Let’s see how Plastic SCM can identify it looking at the next diagram.

What Plastic does is climb the version tree upwards from the starting point you’ve at your workspace. If you start up at revision 1 on /main, changes will only come from this revision itself or the one immediately up. Something different will be displayed if you start from rev 2 at /main/task001.

The good thing is that the Plastic annotate/blame command is not only restricted to climbing the tree up through the branch, but it can also go through the other branches as soon as there are available paths (created when you merge branches), so properly identifying where changes come from.

After merging the two branches, the new revision 3 at /main, will have contributors not only from its previous revs on the branch, but from the other branches. The interesting point to highlight is that changes are not identified as coming from revs 2 and 3, but from the correct ones in the branches.
Considering Plastic SCM promotes using branches as much as possible, and linking branches to tasks/issues/defects on your favorite project management/issue tracking system, you’ll be able to track where exactly changes came from.
Let’s now go through a step by step example, using the command line, to explain how annotate behaves in a real scenario.
> cm mkwk wk01 .
Workspace wk01 has been correctly created
> cm co .
The selected items are about to be checked out. Please wait ...
Item . was correctly checked out
> cm add hostname.cs
The selected items are about to be added. Please wait ...
Item hostname.cs was correctly added
> cm ci hostname.cs . -c="initial commit"
The selected items are about to be checked in. Please wait ...
Checking in hostname.cs ... Done
Checking in d:\data\code\testwkspaces\wk01 ... Done
Created changeset cs:1@br:/main@rep:default@repserver:BEARDTONGUE:8084
Let's create a couple of smart branches from the CLI
> cm mkbr br:/main/task001
> cm sbb br:/main/task001 cs:1
A new base has been set for the branch br:/main/task001.
A checkpoint changeset cs:2@rep:default@repserver:localhost:8084 has been created
> cm mkbr br:/main/task002
> cm sbb br:/main/task002 cs:1
A new base has been set for the branch br:/main/task002.
A checkpoint changeset cs:3@rep:default@repserver:localhost:8084 has been created
And now make a change on the main branch.
I'll be using a co/ci cycle, but as you'll see below, you can follow a commit-only cycle with Plastic too.
> cm co hostname.cs
The selected items are about to be checked out. Please wait ...
Item hostname.cs was correctly checked out
> // edit hostname.cs
> cm ci hostname.cs -c="class name changed"
The selected items are about to be checked in. Please wait ...
Checking in hostname.cs ... Done
Created changeset cs:4@br:/main@rep:default@repserver:BEARDTONGUE:8084
Now switch to task001.
> cm stb br:/main/task001
> cm co hostname.cs
The selected items are about to be checked out. Please wait ...
Item hostname.cs was correctly checked out
> // edit hostname.cs
> cm ci hostname.cs -c="variable name changed"
The selected items are about to be checked in. Please wait ...
Checking in hostname.cs ... Done
Created changeset cs:5@br:/main/task001@rep:default@repserver:BEARDTONGUE:8084
And now I'll show a ci only cycle
> // edit hostname.cs
> cm ci hostname.cs -c="another var name changed"
The selected items are about to be checked in. Please wait ...
Checking in hostname.cs ... Done
Created changeset cs:6@br:/main/task001@rep:default@repserver:BEARDTONGUE:8084
> // edit hostname.cs
> cm ci hostname.cs -c="more info printed"
The selected items are about to be checked in. Please wait ...
Checking in hostname.cs ... Done
Created changeset cs:7@br:/main/task001@rep:default@repserver:BEARDTONGUE:8084
Now onto task002
> cm stb br:/main/task002
> // edit hostname.cs
> cm ci hostname.cs -c="usage controlled"
The selected items are about to be checked in. Please wait ...
Checking in hostname.cs ... Done
Created changeset cs:8@br:/main/task002@rep:default@repserver:BEARDTONGUE:8084
> // edit hostname.cs
> cm ci hostname.cs -c="usage with info"
The selected items are about to be checked in. Please wait ...
Checking in hostname.cs ... Done
Created changeset cs:9@br:/main/task002@rep:default@repserver:BEARDTONGUE:8084
Let's go back to br:/main and run the annotate before merging.
> cm stb br:/main
> cm blame hostname.cs
pablo br:/main#0 using System;
pablo br:/main#0 using System.Net;
pablo br:/main#0
pablo br:/main#0 namespace gethostname
pablo br:/main#0 {
pablo br:/main#1 class GetHostNameTestProgram
pablo br:/main#0 {
pablo br:/main#0 [STAThread]
pablo br:/main#0 static void Main(string[] args)
pablo br:/main#0 {
pablo br:/main#0 string howtogeek = args[0];
pablo br:/main#0 IPHostEntry hentry = Dns.GetHostByName(howtogeek);
pablo br:/main#0
pablo br:/main#0 foreach (IPAddress theaddress in hentry.AddressList)
pablo br:/main#0 {
pablo br:/main#0 Console.WriteLine(theaddress.ToString());
pablo br:/main#0 }
pablo br:/main#0 }
pablo br:/main#0 }
pablo br:/main#0 }
And now on the branches:
> cm stb br:/main/task001
> cm blame hostname.cs
pablo br:/main#0 using System;
pablo br:/main#0 using System.Net;
pablo br:/main#0
pablo br:/main#0 namespace gethostname
pablo br:/main#0 {
pablo br:/main#0 class Class1
pablo br:/main#0 {
pablo br:/main#0 [STAThread]
pablo br:/main#0 static void Main(string[] args)
pablo br:/main#0 {
pablo br:/main/task001#0 string hostName = args[0];
pablo br:/main/task001#0 IPHostEntry hentry = Dns.GetHostByName(hostName);
pablo br:/main#0
pablo br:/main/task001#2 Console.WriteLine("Addresses: {0}", hostName);
pablo br:/main/task001#1 foreach (IPAddress address in hentry.AddressList)
pablo br:/main#0 {
pablo br:/main/task001#1 Console.WriteLine(address.ToString());
pablo br:/main#0 }
pablo br:/main#0 }
pablo br:/main#0 }
pablo br:/main#0 }
> cm stb br:/main/task002
> cm annotate hostname.cs
pablo br:/main#0 using System;
pablo br:/main#0 using System.Net;
pablo br:/main#0
pablo br:/main#0 namespace gethostname
pablo br:/main#0 {
pablo br:/main#0 class Class1
pablo br:/main#0 {
pablo br:/main#0 [STAThread]
pablo br:/main#0 static void Main(string[] args)
pablo br:/main#0 {
pablo br:/main/task002#0 if( args.Lenght == 0 )
pablo br:/main/task002#0 {
pablo br:/main/task002#1 Console.WriteLine("usage: hostname name");
pablo br:/main/task002#1 Console.WriteLine("\tname of your host");
pablo br:/main/task002#0 return;
pablo br:/main/task002#0 }
pablo br:/main/task002#0
pablo br:/main#0 string howtogeek = args[0];
pablo br:/main#0 IPHostEntry hentry = Dns.GetHostByName(howtogeek);
pablo br:/main#0
pablo br:/main#0 foreach (IPAddress theaddress in hentry.AddressList)
pablo br:/main#0 {
pablo br:/main#0 Console.WriteLine(theaddress.ToString());
pablo br:/main#0 }
pablo br:/main#0 }
pablo br:/main#0 }
pablo br:/main#0 }
Let's merge the branches back to main:
> cm stb br:/main
Plastic is updating your workspace. Wait a moment, please ...
Copied hostname.cs
> cm merge br:/main/task001 --merge
Merge needed on item hostname.cs
from br:/main/task001#2
to br:/main#1 base br:/main#0.
Changed by both contributors.
Merging hostname.cs
Merge done
> cm ci hostname.cs
The selected items are about to be checked in. Please wait ...
Checking in hostname.cs ... Done
Created changeset cs:10@br:/main@rep:default@repserver:BEARDTONGUE:8084
And blame:
> cm blame hostname.cs
pablo br:/main#0 using System;
pablo br:/main#0 using System.Net;
pablo br:/main#0
pablo br:/main#0 namespace gethostname
pablo br:/main#0 {
pablo br:/main#1 class GetHostNameTestProgram
pablo br:/main#0 {
pablo br:/main#0 [STAThread]
pablo br:/main#0 static void Main(string[] args)
pablo br:/main#0 {
pablo br:/main/task001#0 string hostName = args[0];
pablo br:/main/task001#0 IPHostEntry hentry = Dns.GetHostByName(hostName);
pablo br:/main#0
pablo br:/main/task001#2 Console.WriteLine("Addresses: {0}", hostName);
pablo br:/main/task001#1 foreach (IPAddress address in hentry.AddressList)
pablo br:/main#0 {
pablo br:/main/task001#1 Console.WriteLine(address.ToString());
pablo br:/main#0 }
pablo br:/main#0 }
pablo br:/main#0 }
pablo br:/main#0 }
Second branch:
> cm merge br:/main/task002 --merge
Merge needed on item hostname.cs
from br:/main/task002#1
to br:/main#2 base br:/main#0.
Changed by both contributors.
Merging hostname.cs
Merge done
> cm ci hostname.cs
The selected items are about to be checked in. Please wait ...
Checking in hostname.cs ... Done
Created changeset cs:11@br:/main@rep:default@repserver:BEARDTONGUE:8084
> cm blame hostname.cs
pablo br:/main#0 using System;
pablo br:/main#0 using System.Net;
pablo br:/main#0
pablo br:/main#0 namespace gethostname
pablo br:/main#0 {
pablo br:/main#1 class GetHostNameTestProgram
pablo br:/main#0 {
pablo br:/main#0 [STAThread]
pablo br:/main#0 static void Main(string[] args)
pablo br:/main#0 {
pablo br:/main/task002#0 if( args.Lenght == 0 )
pablo br:/main/task002#0 {
pablo br:/main/task002#1 Console.WriteLine("usage: hostname name");
pablo br:/main/task002#1 Console.WriteLine("\t name of your host");
pablo br:/main/task002#0 return;
pablo br:/main/task002#0 }
pablo br:/main/task002#0
pablo br:/main/task001#0 string hostName = args[0];
pablo br:/main/task001#0 IPHostEntry hentry = Dns.GetHostByName(hostName);
pablo br:/main#0
pablo br:/main/task001#2 Console.WriteLine("Addresses: {0}", hostName);
pablo br:/main/task001#1 foreach (IPAddress address in hentry.AddressList)
pablo br:/main#0 {
pablo br:/main/task001#1 Console.WriteLine(address.ToString());
pablo br:/main#0 }
pablo br:/main#0 }
pablo br:/main#0 }
pablo br:/main#0 }
How does the vtree look?
And finally a graphic explaining the annotate I just showed above.

It's also possible to decorate each line with the comment:
>cm blame hostname.cs --format="'{comment, -24}'{content}"
'initial commit 'using System;
'initial commit 'using System.Net;
'initial commit '
'initial commit 'namespace gethostname
'initial commit '{
'class name changed ' class GetHostNameTestProgram
'initial commit ' {
'initial commit ' [STAThread]
'initial commit ' static void Main(string[] args)
'initial commit ' {
'usage controlled ' if( args.Lenght == 0 )
'usage controlled ' {
'usage with info ' Console.WriteLine("usage: hostname name");
'usage with info ' Console.WriteLine("\t name of your host");
'usage controlled ' return;
'usage controlled ' }
'usage controlled '
'variable name changed ' string hostName = args[0];
'variable name changed ' IPHostEntry hentry = Dns.GetHostByName(hostName);
'initial commit '
'more info printed ' Console.WriteLine("Addresses: {0}", hostName);
'another var name changed' foreach (IPAddress address in hentry.AddressList)
'initial commit ' {
'another var name changed' Console.WriteLine(address.ToString());
'initial commit ' }
'initial commit ' }
'initial commit ' }
'initial commit '}
Enjoy!
Friday, April 03, 2009
Using Changes app
As most of us Mac developers will be aware, Xcode comes with FileMerge, but sometimes you just need a little bit extra. I recently came across Changes, here's how to use it with Plastic.
After downloading, install the Terminal Utility to give yourself the command line interface. Then, from within a workspace, you can diff two revisions like so (I'm using BASH):
$ chdiff <(cm cat GameScene.mm#br:/main#1) <(cm cat GameScene.mm#br:/main#LAST)
After downloading, install the Terminal Utility to give yourself the command line interface. Then, from within a workspace, you can diff two revisions like so (I'm using BASH):
$ chdiff <(cm cat GameScene.mm#br:/main#1) <(cm cat GameScene.mm#br:/main#LAST)
To get this working from within the Plastic GUI client, we'll need to edit the client.conf file which is located in ~/.plastic/client.conf.
Find the section <DiffTools>, and a few lines down replace the "mergetool" entry with this:
<string>/usr/bin/chdiff "@sourcefile" "@destinationfile"</string>
Restart the Plastic GUI client and diff away.

Labels:
Mac
Subscribe to:
Posts (Atom)
Labels
- Agile (1)
- annotate (1)
- backend (2)
- best practices (2)
- branch diagram (2)
- branching (3)
- c# (7)
- Cmmi (1)
- ddj (3)
- delphi (2)
- development (14)
- distributed (6)
- eclipse (1)
- email (1)
- Functional Testing (1)
- git (1)
- GUI (1)
- integrations (9)
- logging (1)
- Mac (1)
- merging (3)
- mono (51)
- news (34)
- news merging (1)
- plastic (19)
- remote (1)
- replicate (1)
- scm (41)
- Scrum (1)
- secure channel (1)
- security (2)
- selectors (3)
- solaris (2)
- ssl (1)
- task (2)
- testing (5)
- visual studio (4)
Blog Archive
-
►
2008
(69)
-
►
August
(10)
- What's coming? New Visual Studio AddIn
- Configure SQL Server database backend
- Decompressing zip files with C#
- Plastic SCM working with Trac II
- Building task branches with CruiseControl
- How to use Plastic SCM and TechExcel DevTrack II
- Plastic SCM working with Trac
- Xmerge tool to handle refactors (screencast)
- 4 steps to make version control shine
- How to use Plastic SCM and TechExcel DevTrack I
-
►
August
(10)