Feeds:
Posts
Comments

As part of my continuous integration builds using CruiseControl, I’ve fallen into the habit of the following pattern:

  1. Perform an SVN Update (get the latest release)
  2. Overwrite the updated project directory with a set of static files. For example, if my project lives in ${cc.home}/projects/${project.name}, I’ll have another directory under ${cc.home}/nonvcsfiles/${project.name} in which I store unversioned content.
  3. Perform the build
  4. Copy out the build artifacts.

Why do I follow such a pattern, you ask? The reasons are twofold:

First, I deal with some rather complex deployments to multiple servers, etc. and this is an easy way of overwriting properties files, web.xml files (Java), and web.config files (.NET) with server specific values. Since I also use CruiseControl to deploy to these servers as part of a larger, integration test scheme, I might have the same build doing a lot of different things. This way, I can store a directory of new or modified files that is simply xcopied over the build directory AFTER the SVN update. When producing artifacts such as WAR files, it allows me to pre-tailor the web.xml file prior to deployment.

Second, it allows me to copy in large quantities of binary files that might be linked in. A number of my projects are now making use of Maven and Artifactory to maintain version relationships to Jar files, etc., and I’m aware that you can use svn:externals to store external libraries or code. In some cases, however, I’m using the same CruiseControl instances to build .NET, Java (ant) and Java (maven) projects all at once, and the simplest thing to do is copy external library binaries into the requisite lib directories without putting them explicitly under version control. Maybe you’ve got a problem with this, and I can understand that, but sometimes, the quick solution is the easy solution. We keep good records of our library dependencies, and store them under a directory structure that makes versioning evident; additionally, we document the dependencies and versions in a repeatable way. Enough about that, that’s another holy war…

The net result of this is that once I’m done with a build in CruiseControl, my build directory is littered with modified configuration files, and newly copied binary libraries and some other crud. The question is, what do you do to revert your build directory back to it’s pristine, trunk versioned goodness?

The answer is twofold: revert any modified files using svn revert, and then delete unversioned files and directories.

The second part of that turned out to be a little trickier than I would have thought. If you want to delete unversioned files automatically, you’ve got a bit of problem: you need some external scripting or a quick macro / command line argument, which required some research.

After a little looking, I found a nice summary of methods that you can use at this link: Automatically Remove Subversion Unversioned Files. It shows a number of methods and number of scripting languages.

For my use, I need to do this on a Windows 2003 machine with the subversion command line tools. Unfortunately, in the link above, I did find a solution for a command line script on windows, but it doesn’t work for directories, and it doesn’t work for files with spaces in the name. However, with a few tweaks, here’s the three lines of script needed.

svn revert -R .
for /f "tokens=1*" %i in ('svn status ^| find "?"') do del /q "%j"
for /f "tokens=1*" %i in ('svn status ^| find "?"') do rd /s /q "%j"

The first line reverts any of the files that are modified. The second line deletes any unversioned files, and the third line deletes any unversioned directories (and their contents, recursively).

There are two GREAT things about this process:

  • If there are certain build files or directories that you don’t want deleted or cleaned up, you can add these to the svnignore list, and these will be ignored by version control and NOT deleted via this process.
  • This ensures that any additional non-versioned files that make it onto your build server over time are accounted for, either appearing in version control, or appearing the special nonvcsfiles directories.

The final step is to drop these items into an ANT task that can be called either before a new build, or at the end of a build to clean up. Just use the exec method for each line, like this:

<!-- clean out nonversioned files -->
<target name="clean">
<!-- revert all SVN version controlled files -->
<exec executable="svn">
<arg value="revert"/>
<arg value="-R"/>
<arg value="."/>
</exec>

<!-- delete all unversioned files not explicit ignored by SVN-->
<exec executable="cmd">
<arg value="/c"/>
<arg value="for /f &quot;tokens=1*&quot; %i in ('svn status ^| find &quot;?&quot;') do del /q &quot;%j&quot;"/>
</exec>

<!-- delete all unversioned directories not explicit ignored by SVN-->
<exec executable="cmd">
<arg value="/c"/>
<arg value="for /f &quot;tokens=1*&quot; %i in ('svn status ^| find &quot;?&quot;') do rd /s /q &quot;%j&quot;"/>
</exec>

</target>

Having recently been through a Snow Leopard upgrade on my Macbook Pro (2.4 GHz Core Duo model), I previously noted a number of issues with my Ruby on Rails install related to two core issues:

  • Java is automatically upgraded to version 1.6
  • Many of your Ruby gems need to be reinstalled due to Snow Leopard’s 64 bit support

My latest issue is around my Logitech keyboard and mouse. They still work, but the Logitech Control Center doesn’t. This is message I see in the Control Center: “No Logitech Device Found”.

The solution appears to be a simple reinstallation of the Logitech drivers, which can be found here:
Logitech Control Center

Alternately, I found some great instructions at TUAW.


I’ve starting working in Git for some of my Ruby work, and I’m trying to work some Eclipse integration into the mix. I’m a big fan of IDE’s from the standpoint that IDE’s can provide some real efficiencies for certain environments. For example, I use Aptana Studio for my Ruby development, and I really like some of the features.

One of my complaints so far, however, is that Git has lagged behind Subversion in terms of quality integration with the IDE, or simply visual client inspectors in general. Frankly, when I work in version control (such as subversion), I expect that my IDE will be able to diff between two branches in the version control system (VCS), and I expect to be able to “double click” a file, and see a simple diff between two versions of the same file. That should ALL be integrated.

I shouldn’t be hand cobbling together a loose consolidation of tools that all don’t work very well in order to inspect the files and work with them for a diff’ing operation, and when I reconcile code changes between two branches… well, excuse me if I think that the best tools should have those features integrated. Purists might disagree, but if I’m at the command line, manually comparing text diffs between two files… I don’t feel that efficient.

Let’s be honest here moment #1:

Tortoise, the windows client for Subversion releases by tigris.org, is one of the MAIN reasons behind the widespread acceptance of Subversion. What does it do well? It provides an environment for quickly browsing and merging changes graphically, and while it is an external tool, it’s tied directly into the file explorer (like it or hate it, users understand it).

Let’s be honest here moment #2:

Not all developers have the same skill level. Not all developers are going to immediately understand how to transition to a new VCS tool, and they aren’t all going to jump there unless the basics (installing it, basic checkin / out, basic merge functionality) is at LEAST on par with what they currently use. At least not en masse.

It’s this fact alone that was responsible for some of the changes in the Eclipse development platform with respect to downloading and installing things like VCS / Team providers. The menu completely changed in the most recent versions to a graphical menu that prompts you to download the appropriate native SVN or SVNkit libraries. Basically, you’ll get a significant uptick in usage if you spend more time on making the initial install painless.

This brings me to egit, which is the latest effort to bring Git functionality to Eclipse through the Mylyn team integration. It looks very basic for the moment, and I certainly applaud the effort. This is what it will take to bring Git mainstream. But…. in spite of the simplicity, I can’t get it to work for some Git projects.

Simply trying to share a new project through the team menu results, for me, the dreaded “spinning beachball of death”, meaning that that eclipse simply locks up… (boo!). After selecting my new project (already under Git control), my system simply locks up.

200909240934.jpg

The primary issue here seems to be that my project is ALREADY under Git control. If I attempt to use the Team -> Share -> Git option for non-VCS controlled directories, things seem to work normally.

Anyhow, I’ve logged what I think is my issue over at the google code issue tracker for the egit project. Let me know if you see something similar yourselves!

http://code.google.com/p/egit/issues/detail?id=111

Other than that, however, I certainly appreciate the first steps that are being taken by the egit team!

After upgrading to Snow Leopard, I was greeted with the following upon trying to run my latest Ruby application:

/path/to/gems/ruby-debug-base-0.10.3/lib/ruby_debug.bundle: dlopen(/path/to/gems/ruby-debug-base-0.10.3/lib/ruby_debug.bundle, 9): no suitable image found.  Did find: (LoadError)
/path/to/gems/ruby-debug-base-0.10.3/lib/ruby_debug.bundle: no matching architecture in universal wrapper -/path/to/gems/ruby-debug-base-0.10.3/lib/ruby_debug.bundle

/path/to/gems/linecache-0.43/lib/../lib/trace_nums.bundle: dlopen(/path/to/gems/linecache-0.43/lib/../lib/trace_nums.bundle, 9): no suitable image found.  Did find: (LoadError)
/path/to/gems/linecache-0.43/lib/../lib/trace_nums.bundle: no matching architecture in universal wrapper - /path/to/gems/linecache-0.43/lib/../lib/trace_nums.bundle

/path/to/gems/activerecord-2.3.3/lib/active_record/connection_adapters/abstract/connection_specification.rb:76:in `establish_connection': Please install the postgresql adapter: `gem install activerecord-postgresql-adapter` (dlopen(/path/to/gems/pg-0.8.0/lib/pg.bundle, 9): no suitable image found.  Did find: (RuntimeError)
/path/to/gems/pg-0.8.0/lib/pg.bundle: no matching architecture in universal wrapper - /path/to/gems/pg-0.8.0/lib/pg.bundle)

I did find a quick fix: basically, the native system gems need to be reinstalled for 64-bit gems:

I found a good script for doing this at:

http://stackoverflow.com/questions/1367380/snow-leopard-64-bit-ruby-gem-problem

From the irb interface, try this:

$ irb
  irb> `gem list`.each_line {|line| `sudo env ARCHFLAGS="-arch x86_64" gem install #{line.split.first}`}

After about 20 minute of trashing, my system was up and functional again!

— UPDATE —
As pointed out by Jeffrey Lee, this could be a little more verbose with the following modifications:

`gem list`.each_line {|line| puts "Installing #{line.split.first}"; `sudo env ARCHFLAGS="-arch x86_64" gem install #{line.split.first}`}
wurdle-Sept19-2009

wurdle-Sept19-2009

mediconnect1.png
In this article, I’ll be describing my setup for a simple iPhone application that I’ve built using Ruby on Rails.The primary objective was to quickly build out a prototype application demonstrating the use of a mobile device in entering critical data in the field (in this case, for Pharmaceutical Sales Reps) as well as content integration to another application for rapidly searching and repurposing legacy Word and Excel 2003 content (that part comes later!)

This is a high-level description, so I’ll be only providing an overview of some of the rails functionality, so those people looking for a full walkthrough might be a little disappointed.

PART 1 – Building the Basic Application and Simple Data Entry

My environment:

OS: Macbook Pro (Leopard 10.5.7)

Primary Dev Environment: Eclipse (Galileo) + Aptana RadRails (v1.5.1)

Target iPhone Device: iPhone 3G

My Plugins / Gems/ Rails Addons

jRails v0.4 – An excellent substitute for the default prototype libraries used in Rails.

tank-engine – austinrfnd’s branch branch of Noel Rappin’s tank-engine project.

Creating the Basic Application

After creating the basic application in Aptana studio, I created very a very basic page for handing new medical information requests:

script/generate scaffold mirequest summary:string description:string potential_ae:string potential_pc:string primaryproduct

At this point, I could access basic RESTful functions for index, new, edit, etc. through a standard browser.

Adding iPhone Functionality

In order to best use the iPhone, I first started with Noel Rappin’s tank-widget plug-in. This is simple successor to to his original rails-IUI plugin, but features integration with the jQuery library instead of using the iui javascript and css files. I actually started with one of the most current branches of this code based on some changes by austinrfnd in his own branch (tank-engine).

There are some good demonstrations of using this functionality in a series of articles hosted by IBM;

Developing iPhone applications using Ruby on Rails and Eclipse…

So, setting up the environment looked something like this:

Install the jQuery Rails plugin (my version is 0.4)

sudo script/plugin install git://github.com/aaronchi/jrails.git

Manually copy the javascript files in the plugin. to your javascripts directory.

Install the tank-engine widget

sudo script/plugin install git://github.com/austinrfnd/tank-engine.git

rake tank_engine:install

At this point, I needed to modify a few files to add the iPhone rendering format to my mirequests index view.

Copy and rename views/mirequests/index.html.erb to views/mirequests/index.iphone.erb.

The next step is to enable the controller to detect iPhone specific requests and to include the plug-in helpers for tank-engine.

  acts_as_iphone_controller :test_mode => true

  include TankEngineHelper

Finally, you can get a basic set of buttons and a title-bar by editing the index.iphone.erb.

Here’s what mine looks like.

%=

l = { :caption => ‘Create MI’, :url => new_mirequest_path, :html_options => { :class => ‘te_slide_left’ } }

r = { :back => true, :caption => ‘Back’, :url => “/”, :html_options => {} }

te_navigation_bar( r, “MI Request”, l ) %>

<% panel do %>

<div>

<h2>Pending MI Requests:</h2>

</div>

<% fieldset do %>

<% @mirequests.each do |mirequest| %>

<% row mirequest.summary do %>

<%=h mirequest.description %>

<%= te_link_to ‘Show’, mirequest %>

<% end %>

<% end %>

<% end %>

<% end %>

You can find documentation on these helpers in the tank-engine github site as well as the IBM articles listed above. I did have some formatting issues, however, and the usage of some of the tank-engine helpers wasn’t completely documented. One thing that I learned was that unless you place the row and fieldset helpers inside the panel helper, you won’t get the intended look and feel.

The result should look something like this:

200909111348.jpg

In the next article, we’ll discuss some of the formatting issues and shortcomings with the tank-engine library and how I chose to spice this up a little bit as follows:

200909111352.jpg

Versions of Software Used

  • Mac OS X Leopard 10.5.6
  • Maven 2.0.10

STEPS

Upgrade Maven on Leopard

Download Cocoon

Loading Cocoon Block into Eclipse

From the Command Line

mvn archetype:generate -DarchetypeCatalog=http://cocoon.apache.org

cd /Users/smetker/development/cocoon_dev/svn

mkdir getting-started-app

mvn archetype:generate -DarchetypeCatalog=http://cocoon.apache.org

Choose a number: (1/2/3): 2

Define value for groupId: : com.rwd.infomaestro

Define value for artifactId: : myBlock1

Define value for version: 1.0-SNAPSHOT: : 1.0.0

Define value for package: com.rwd.infomaestro: : com.rwd.infomaestro.myBlock1

mvn archetype:generate -DarchetypeCatalog=http://cocoon.apache.org

Choose a number: (1/2/3): 2

Define value for groupId: : com.rwd.infomaestro

Define value for artifactId: : myBlock1

Define value for version: 1.0-SNAPSHOT: : 1.0.0

Define value for package: com.rwd.infomaestro: : com.rwd.infomaestro.myBlock2

cd myBlock1

mvn eclipse:eclipse

Create the 2nd eclipse project settings

cd ../myBlock2

mvn eclipse:eclipse

cd ..




Choose a number: (1/2/3): 3

Define value for groupId: : com.rwd.infomaestro

Define value for artifactId: : myWebApp

Define value for version: 1.0-SNAPSHOT: : 1.0.0

Define value for package: com.rwd.infomaestro: : com.rwd.infomaestro.myWebApp

cd ..

In order to use blocks as dependencies you need to install them into Maven’s local repository. First go to myBlock1/ and myBlock2/ directory and execute following command:

cd myBlock1
mvn install
cd ..
mvn install


So far the web application myCocoonWebapp doesn’t have any information about the existense of the block myBlock1 and myBlock2. Change this by opening getting-started-app/myCocoonWebapp/pom.xml and add the block as dependency:

<project>
[...]
<dependencies>
<dependency>
        <groupId>com.rwd.infomaestro</groupId>
<artifactId>myBlock1</artifactId>
<version>1.0.0</version>
</dependency>
<dependency>
        <groupId>com.rwd.infomaestro</groupId>
<artifactId>myBlock2</artifactId>
<version>1.0.0</version>
</dependency>
</dependencies>
[...]
</project>


Running Jetty from Command Line (Jetty bundled with Cocoon block)

mvn jetty:run


Debugging Cocoon in Eclipse

Follow the instructions under this link first: Cocoon Main Site – Debugging Cocoon in Eclipse

Using the Jetty launcher is much simpler and you don’t have to create a Java project for each Cocoon application that you want to debug.If you prefer using Jetty 6, you can start Jetty as Java application from within Eclipse. For this purpose

  • download Jetty 6
  • and extract it into a directory of choice. You only have to make sure that it is not a subdirectory of an Eclipse project that is added to your Eclispe workspace.
  • now create a new Java project (e.g. “Jetty6″) in your workspace and add jetty-6.x.jar, jetty-util-6.x.jar, servlet-api.2.5.x.jar and start.jar as library dependencies (all 4 files are part of the official Jetty distribution)
  • add the project(s) that you want to debug as Project References and as Java Build Path – Projects references. This makes it necessary that these projects are added to the current workspace.
  • provide a minimal Jetty configuration file jetty-debug-cocoon.xml, e.g. in the root directory of your “Jetty6″ project

I found this while cleaning out the office the other day. Haven’t seen that many boxes for EMC or Oracle software lately. Is it just me?