I recently developed a useful ANT task to automatically increment a version number on your Java project when using perforce as your source control application. This task is intended to be run as part of an automated build (via cruisecontrol). It checks out version.properties and checks it back in after incrementing.
Notes:
- The task will look for the following files in the same directory as your build.xml. You should be able to figure out what parameters belong in each file by looking at the task. files: version.properties, buildnumber.properties, p4.properties
- In the lines where I print the full version number I have broken it up into two lines for display purposes. In practice you will want to keep it on one line.
<target name="create-label" depends="compile-src">
<copy todir="${ant.library.dir}"
file="medremote_dev/tools/jakarta-oro-2.0.8.jar"
overwrite="false"/>
<property name="p4.properties"
value="p4.local.properties" />
<property file="${p4.properties}" />
<property name="p4.port" value="${p4.port}"/>
<property name="p4.client" value="${p4.client}"/>
<property name="p4.user" value="${p4.user}"/>
<!-- must supply password in globalopts when the perforce server uses sessions -->
<property name="p4.globalopts" value="-P ${p4.password}"/>
<property name="p4.path" value="{p4.path}"/>
<echo>p4.path is ${p4.path}</echo>
<!-- sync buildnumber.properties and version.properties for edit -->
<p4sync view="${p4.path}/source/buildnumber.properties"
force="true"
globalopts="${p4.globalopts}"/>
<p4sync view="${p4.path}/source/version.properties"
force="true"
globalopts="${p4.globalopts}"/>
<!-- increment buildnumber.properties -->
<chmod file="buildnumber.properties" perm="ugo+w"/>
<attrib file="buildnumber.properties" readonly="false"/>
<buildnumber file="buildnumber.properties"/>
<tstamp/>
<!-- Updates the version.properties file -->
<property prefix="label" file="version.properties"/>
<property name="new.version.major" value="${label.version.major}"/>
<property name="new.version.minor" value="${label.version.minor}"/>
<property name="new.version.iteration" value="${label.version.iteration}"/>
<property name="new.version.build" value="${build.number}"/>
<property name="new.version.drop" value="${label.version.drop}"/>
<!-- update version.properties -->
<chmod file="version.properties" perm="ugo+w"/>
<attrib file="version.properties" readonly="false"/>
<propertyfile file="version.properties">
<entry key="version.major" value="${new.version.major}"/>
<entry key="version.minor" value="${new.version.minor}"/>
<entry key="version.iteration" value="${new.version.iteration}"/>
<entry key="version.drop" value="${new.version.drop}"/>
<entry key="version.build" value="${new.version.build}"/>
<entry key="version.date" value="${DSTAMP}${TSTAMP}"/>
</propertyfile>
<echo>Creating Label: ${new.version.major}.${new.version.minor}.
${new.version.iteration}.${new.version.build}"</echo>
<p4change description="Increment build number via automatic build"
globalopts="${p4.globalopts}"/>
<!-- open buildnumber.properties and version.properties for edit
(even though we already incremented it)-->
<p4edit view="${p4.path}/source/buildnumber.properties"
change="${p4.change}"
globalopts="${p4.globalopts}"/>
<p4edit view="${p4.path}/source/version.properties"
change="${p4.change}"
globalopts="${p4.globalopts}"/>
<!-- submit properties files to source control after incrementing build -->
<p4submit change="${p4.change}"
globalopts="${p4.globalopts}"/>
<!-- label the project -->
<p4label
name="FX${new.version.major}.${new.version.minor}.
${new.version.iteration}.${new.version.build}"
desc="label created during automatic project build"
view="${p4.path}/..."
globalopts="${p4.globalopts}"/>
</target>
In the Operations Management course I just finished, a group project accounted for a third of the grade. My group was given the topic “Toyota Production System / Lean Manufacturing”. I suggested to the group that we use a Wiki to collaborate on the project.
I installed MediaWiki (the same one used by Wikipedia) on my site and off we were. The wiki did not necessarily determine the outcome of the project(which was a success), but it certainly helped streamline the process. In fact, I think I found a new application for Lean principals – Lean Group Project Collaboration!
You can find the results here: OMIS505 Group Project Wiki
Upsides of Wiki Collaboration
-mobile, accessible repository for keeping research (links and notes)
-gives you the ability to instantly see the latest version of your project (or the outline in our case)
-you can review what changes were made when and by whom, which introduces some accountability into the project
Downsides of Wiki Collaboration
-no mechanism for uploading files (like a powerpoint presentation)
In case you are interested, the final version of our powerpoint is available here:
Group Project Presentation (5MB)

You know, I think he was right.
Recently I started noticing a lot of spam posts on my website. It must be those internet hacker bots! I wondered if I could put one of those fancy image verification things into my site to stave them off. They’re called ‘captchas’ and it turns out that its simple and easy to implement such a thing in Ruby on Rails using the reCaptcha plugin. Here are the instructions I wish I had when I started:
- install the reCaptcha gem. I’m using Aptana/RadRails IDE which has a nice interface to install gems, but I hear you can install it via the command line with something like ‘gem install reCaptcha’
- Register for public and private keys at recaptcha.net .This is also a good tutorial of how a captchas and reCaptcha works. You will have to add your public and private keys to your config/environment.rb file.
- insert the reCaptcha function calls into your code:
recaptcha_tags() – put this into your®html form to generate the challenge image.
verify_recaptcha() – when inserted into the controller, checks the data passed from the form to make sure that the correct ‘answer’ was given. returns boolean
Thats it! Add a comment to test it out!
Training Camps are finished. Madden has been released. Exhibition games are done. Fantasy Drafts have closed…
The NFL season is upon us. The action kicks off in just two days and I CAN’T WAIT!
Go Bears
have switched web hosts as of today from Axishost to Dreamhost. Axishost was very good, but their spamassasin has been broken for about a month and I couldn’t take it anymore!
I’ve also lowered my yearly hosting costs from $72 to $23(Dreamhost promo code: DOIT). We shall see how Dreamhost measures up.
Update: The switch went pretty smooth, although this was the most complicated one yet due to the fact that I’m using Ruby on Rails and running a photo gallery. The procedure was basically:
- Copy Data
- spoof new DNS by modifying ‘hosts’ file. This was required to access phpmysql and to test out the site.
- Export/Import Mysql databases.
- redeploy website.
I can tell the difference with Dreamhost using fastCGI. The site usually loads a lot faster. My only complaint so far is that Dreamhosts spam filtering solution isn’t as good as axishosts. Supposedly I can install a better one but I haven’t gotten around to it yet.
I just got done deleting hundreds of unwanted comments from my gallery software which I can only assume were placed there because of internet hacker bots!
Also, I just realized that my content management system is totally unsecure. If you had the wherewithall I’m sure you could hack my articles up a bazillion ways from Sunday (what does that even mean)?
Things to do:
- - disable guest account for photo gallery and force my friends and family members to register & login just to post a comment on some picture.
- - secure my website. I must remember the words of Uncle Ben: With Great Power (Ruby on Rails) comes great Responsibility (i.e. the site doesn’t secure itself)!
Now that I think of it, I actually have an uncle Ben and I’m not sure he’s ever said that.
UPDATE 6/6/2007 My site is now [more] secure! Take that internet hacker bots!
Google just rolled out a new free 411 service. You can access this awesome service by dialing 1(800)GOOG-411. It prompts you for City & State, then a business name or type. After selecting the business it will connect you automatically. Never again will I have to look up the number for Little Caesers!
The service is completely automated. It uses speech recognition to figure out what you say and some text to speech processor to give you the results. The best part? I hear it uses Nuance’s Dragon engine for Speech Recognition.
Read more about this service at the following URLs
http://labs.google.com/goog411/
Ars Technica Article