April 19, 2012 0

LOAD ALL THE RUBIES!!!

By in ruby

Dangerous Cucumber Loading Issue

I recently discovered a potentially dangerous issue with how cucumber loads ruby files. The standard cucumber project expects a features directory in which to place your .feature files. Standard practice is to place supporting ruby files in features/support and to place step definitions in features/step_definitions, but that’s just convention. Cucumber recursively loads all .rb files under features/ (ensuring only that features/support/env.rb is loaded first). This is all well and good, so long as you actually have a features directory (and it’s in the root of your project). So what happens if you name your features directory something else or your features directory is in a sub-directory? If you remember to tell cucumber which directory to load from, everything is fine (`cucumber alternative_folder/`). If you forget, however, cucumber will dutifully load (recursively) every ruby file it can find!

format_hard_drive.rb

This is still not much of a problem, assuming all your ruby files are just plain old ruby classes or benign ruby scripts. The problem really rears it’s head if, say, you have a utility_scripts directory full of potentially dangerous scripts for setting up project directories, manipulating test databases, or pretty much anything. (Who else has an `rm -rf /` ruby script?)

Cucumber - Load All The Things!!!

Lesson

Name your features directory features.

 
 

Tags: ,

April 17, 2012 0

Fetch and Iterate

By in javascript

Tonight I stumbled across a blog post from the future! Or something like that. On 4/17 at 11:30PM I read a blog post that was published on 4/18 at 1:54. Time zones = time travel. Anyway…

It was about finding a cleaner, more succinct, syntax for a standard pattern:
fetch_data, process_data, rinse and repeat until no more data!

Quick, go read the original post. Don’t worry, it’s short.

{elevator music}

Okay, so how do we improve this? Well, in some languages (like JavaScript, Ruby, PHP, et. al), an assignment expression actually returns a value. And since the expression returns a value, the expression itself can be used as the looping condition, like so:

while(data = fetch()){
  process(data);
}​

Notice the single equals sign? We are doing assignment here, not an equality check. We invoke fetch() and the result is returned and assigned to data. Now the value of data itself is used as the while condition. So the data is continually fetched and processed until fetch() returns a falsy value. (In JavaScript, that would be one of false, undefined, null, 0, "", or NaN)

This is a very common pattern in PHP, especially when fetching/querying data from a database. It’s a much less common pattern in JavaScript, but still quite valid. As is with most useful things, this approach can be misused. It can easily be confused for a typo (missing an equals sign?) so it should be used with care. For instance, ensuring that your fetch() function and data variable are named clearly should make it less likely to be misunderstood. When used appropriately, it can certainly increase the clarity of your code.

 
 

Tags: , , ,

April 3, 2012 0

ANSI color in Windows shells

By in shell

Having used git on windows for over three years now, I’ve fallen back in love with the command line. Bash, of course, not the windows command prompt. Beautiful, ubiquitous, warty bash. Git depends heavily on GNU utilities so on Windows it requires either cygwin or msys. Having been burned by cygwin in the past, I prefer the minimalism and simplicity of msys + mingw. Along with git, the entire ruby ecosystem lives in the shell. However, the numerous tools, gems and utilities that assume standard ANSI color support in the shell began to wear on me. Lo and behold, there is a lovely solution to provide ansi color support for bash (and cmd) on Windows: ansicon.

Download the zip and extract. There are a few ways to install:

  1. Extract to a permanent location (I use C:/bin/ansicon). Execute ansicon.exe -i from within the appropriate directory for your system (x86/x64), and you’re all set. Any new shells (bash and windows cmd included) will autorun the ansicon utility for displaying color output. Be sure not to move the executable prior to running ansicon.exe –u. This removes the registry entry and prevents an ugly error message for every command shell.
  2. Alternatively, place the ansicon executable in your PATH, or add its location to your PATH. Then you can launch ansicon for a session with ansicon.exe –p.

This utility has been working great for my on Windows XP. I’ve been having trouble getting it to work on Windows 7, but I hear it should be supported. I’ll post an update when the Windows 7 issue is resolved.

Update

Root cause, uncovered! If you use JRuby with a 64-bit JVM on Windows x64, ansicon won’t work. The issue is that ansicon (64-bit) is capable of injecting into 32-bit processes, but not vice versa. Currently, the JRuby launcher is a 32-bit executable. Thus, if you’re running a 64-bit shell (cmd, bash, or otherwise), ansicon will inject correctly into that process. It will then inject successfully into the 32-bit JRuby launcher process. At this point, for all intents and purposes, you’re running the 32-bit version of ansicon. Thus, if you’re running JRuby on a 64-bit JVM, then 32-bit ansicon is not able to inject into 64-bit JVM. There is an open feature request for JRuby to ship its 64-bit version with a 64-bit launcher. You should vote for this feature. I also hear that adoxa (Jason Hood) has a potential fix for this issue in the works. Stay posted.

Of course, the easiest solution at the moment is to ensure that JRuby uses a 32-bit JVM. Just change (or set) your JAVA_HOME environment variable to point to a 32-bit JVM and you’re golden.

Update 2: Issue Resolved

The latest 64-bit binaries (ansi6432.zip) have fixed the issue. Just download and extract them over-top the 1.51 version.

 
 

Tags: , , ,

November 15, 2011 1

Subdirectory Checkouts with git sparse-checkout

By in git

If there is one thing I miss about SVN having switched to git (and trust me, it’s the only thing), it is the ability to checkout only a sub-tree of a repository. As of version 1.7, you can check out just a sub-tree in git as well! Now not only does git support checking out sub-directories, it does it better than subversion!

New Repository

There is a bit of a catch-22 when doing a sub-tree checkout for a new repository. In order to only checkout a sub-tree, you’ll need to have the core.sparsecheckout option set to true. Of course, you need to have a git repository before you can enable sparse-checkout. So, rather than doing a git clone, you’ll need to start with git init.

  1. Create and initialize your new repository:

    mkdir <repo> && cd <repo>
    git init
    git remote add –f <name> <url>
  2. Enable sparse-checkout:

    git config core.sparsecheckout true
  3. Configure sparse-checkout by listing your desired sub-trees in .git/info/sparse-checkout:

    echo some/dir/ >> .git/info/sparse-checkout
    echo another/sub/tree >> .git/info/sparse-checkout
  4. Checkout from the remote:

    git pull <remote> <branch>

Existing Repository

If you already have a repository, simply enable and configure sparse-checkout as above and do git read-tree.

  1. Enable sparse-checkout:

    git config core.sparsecheckout true
  2. Configure sparse-checkout by listing your desired sub-trees in .git/info/sparse-checkout:

    echo some/dir/ >> .git/info/sparse-checkout
    echo another/sub/tree >> .git/info/sparse-checkout
  3. Update your working tree:

    git read-tree -mu HEAD

Modifying sparse-checkout sub-trees

If you later decide to change which directories you would like checked out, simply edit the sparse-checkout file and run git read-tree again as above.

Be sure to read the documentation on read-tree/sparse-checkout. The sparse-tree file accepts file patterns similar to .gitignore. It also accepts negations—enabling you to specify certain directories or files to not checkout.

Now there isn’t anything that svn does better than git!

 
 

Tags: , , ,

July 5, 2011 0

JRuby on MSYS | MinGW

By in jruby, ruby

For many Windows users, like myself, the easiest way to get up and running with Ruby is to install JRuby. If you’re like me, then you may also be a Git user. Now this is just a hunch, but I would wager that if you’re a git user and interested in ruby, then there is a high probability that you’re also a fan of proper *nix shells. If all of the above hold true, keep reading.

As a Windows user without access to a proper command line shell (and too tired of fighting with cygwin), I was delighted to have a bash shell at my command after installing msysgit. The subsystem beneath msysgit is MSYS | MinGW. According to their site, MinGW (“Minimalistic GNU for Windows”) is a collection of freely available and freely distributable Windows specific header files and import libraries combined with GNU toolsets that allow one to produce native Windows programs that do not rely on any 3rd-party C runtime DLLs.[1] In addition to MinGW, MSYS is a collection of GNU utilities such as bash, make, gawk and grep to allow building of applications and programs which depend on traditionally UNIX tools to be present. It is intended to supplement MinGW and the deficiencies of the cmd shell. [2] In simplest terms, MSYS | MinGW is a lightweight Cygwin. It is ‘lightweight’ because it doesn’t provide *nix system calls or a POSIX emulation layer. However, if you’re looking for the standard *nix toolsets on Windows, MSYS | MinGW is a great utility.

NoClassDefFoundError: org/jruby/Main

With MinGW installed along with msysgit, I’ve returned to the bash shell as my primary shell on Windows. However, because MinGW is not quite *nix, nor is it really Windows, the standard JRuby installation doesn’t work out of the box. After running the JRuby installer, you pop open a bash shell and run jruby -v to verify the jruby/ruby version. Or you try to run irb or jirb to get a ruby console. Or you try to install a gem via gem install. Up pops an giant error:

Exception in thread "main" java.lang.NoClassDefFoundError: org/jruby/Main
Caused by: java.lang.ClassNotFoundException: org.jruby.Main
        at java.net.URLClassLoader$1.run(URLClassLoader.java:202)
        at java.security.AccessController.doPrivileged(Native Method)
        at java.net.URLClassLoader.findClass(URLClassLoader.java:190)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:307)
        at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:248)
Could not find the main class: org.jruby.Main.  Program will exit.

Of Shells and Executables

So what’s the problem? The JRuby installer for Windows includes quite a bit of stuff in the bin directory. First and foremost is jruby.exe. This is the real executable for Windows. You’ll also see jruby.bat. This is just a wrapper which calls jruby.exe. (I assume this is an backwards-compatibility artifact from before the jruby.exe launcher existed.) You’ll also notice an extension-less jruby shell script. When you execute any of these jruby commands (jruby, irb, jirb, gem, etc) from a Windows command prompt, it will fire off jruby.exe or jruby.bat because those are the file extensions it is configured to look for. However, the MinGW bash shell prefers the jruby shell script and executes that first. Near the top of this shell script, you’ll find a block of code that determines the OS the shell is running under.

# ----- Identify OS we are running under ---------------
case "`uname`" in
  CYGWIN*) cygwin=true;;
  Darwin) darwin=true;;
esac

The shell script assumes we’re either *nix, CYGWIN or Darwin (Mac). This is understandable as the Windows Command Prompt will not attempt to execute this script. However, now that we’re using a proper bash shell with MinGW, we need to tell JRuby to expect MinGW.

The Fix(es)

The simplest fix is to delete the shell script. This way, when MinGW searches for an executable, the first it finds is jruby.exe. Alternatively, you can add the following line to the case statement in the jruby script:

MINGW*) jruby.exe "$@"; exit $?;;

This line simply checks if running on MinGW and, if so, executes jruby.exe passing along any parameters. The shell script returns with the same exit code as jruby.exe. Now the case statement should look like:

# ----- Identify OS we are running under ---------------
case "`uname`" in
  CYGWIN*) cygwin=true;;
  Darwin) darwin=true;;
  MINGW*) jruby.exe "$@"; exit $?;;
esac

OSS and GitHub to the Rescue

Thanks to JRuby being an Open Source project, and GitHub for having awesome collaboration tools, this patch was submitted and accepted to the JRuby project on GitHub. Future installations of JRuby should work on MinGW out of the box.

 
 

Tags: , , ,

June 30, 2011 4

Ubiquity in Firefox 5

By in ubiquity

As may be clear by my ubiquitycommands github repository, I am an avid Ubiquity user. So much so, in fact, that I delayed upgrading to Firefox 5 until I was able to find a version of Ubiquity that works with Firefox 5. Wonder of wonders, I have found that version.

Satyr Murky continues to work on a community-maintained fork of the original Mozilla.org version of Ubiquity. Luckily for us, it works in Firefox 5.

Thank you, Satyr!

Download: Ubiquity (tip.xpi)

 
 

Tags: ,

June 27, 2011 1

Test Your Transformations

By in .net

Web.config transforms are a really great tool for setting up environment-specific configuration files. However, the transform syntax can be a bit obscure, and tracking down configuration bugs is just painful.

For this, there is a great testing tool hosted on AppHarbor. Paste in your web.config contents in one box, drop in your transform in another and out comes the transformed web.config. Never waste time messing with your web.config transforms again!

screenshot of the web.config transform tester service

 
 

Tags: , , ,

June 20, 2011 2

Google Calendar > Lotus Notes

By in productivity

Are you forced to use Lotus Notes at work? Do you prefer Google Calendar? Would you like to have your Lotus Notes calendar synced to your Google calendar? Solution: CalSync!

CalSync is a great little utility that runs in the background and automatically syncs your Lotus Notes calendar with Google Calendar. You can download it from SourceForge. It’s a standalone application that doesn’t require installation. Simply extract the zip file into a directory of your choosing and open the executable. You’ll need to provide you Lotus Notes account information, as well as your Google account information. (I recommend using Google’s 2-factor authentication and setting up an application-specific password for CalSync.)

screenshot of calsync account info dialog

After providing your account information, you can configure how you would like it to sync with Google Calendar. Personally, I recommend creating a new Google Calendar that is dedicated to syncing with your Lotus Notes calendar.

screenshot of calsync account options dialog

There are plenty of additional configuration options to customize how/when your calendar items are synced. And, of course, to have it start with windows, simply add a shortcut to CalSync to your Startup folder. Now you can get your Lotus Notes work calendar on your smartphone via Google!

 
 

Tags: , ,

June 16, 2011 0

Userscripts, Userstyles and Ubiquity

By in ubiquity, userscripts, userstyles

A while ago I described how to merge two git repositories into one. I discovered how to do this as I was attempting to consolidate a number of git repositories that I have on GitHub. Previously, I had a separate git repository for each user script, user style and ubiquity command that I’ve written. It was getting unmanageable so I decided to create a single git repository for my user scripts, another for my user styles, and a third for my ubiquity commands. You can now find my them all on GitHub.

Userscripts

[GitHub repository]

Tweetapaper
adds ‘Tweet’ links to articles in your Instapaper queue. [install from Userscripts.org]
Instasubmit
auto-submits the Instapaper Add form when loaded via Google Reader’s Send To Instapaper action. [install from Userscripts.org]
Radapaper
adds ‘Radbox’ links to articles in your Instapaper queue. [install from Userscripts.org]
TreasuryDirect Login
makes the password field editable so that you can use the keyboard to log in. [install from Userscripts.org]

Userstyles

[GitHub repository]

Gmail – Icons for S/Mime Messages
adds icons to messages in Gmail which have been digitally signed or encrypted using S/MIME. [install from Userscripts.org]
Tab Notifier
highlights any open Gmail, Google Reader, Google Voice, and Facebook tab when there are unread items. [install from Userscripts.org]

Ubiquity Commands

[GitHub repository]

ClaimID
easily claim URLs under your ClaimID account. [install from GitHub]
Wishlistr
easily add items to a Wishlistr wishlist. [install from GitHub]
 
 

Tags: , ,

March 23, 2011 4

Merge Two Git Repositories Into One

By in git

A few weeks ago I tweeted: “Just did 2 subtree merges in order to combine 2 partially-related git repos into a single repo and still maintain history. #gitrocks” Wanna learn how to do it? Here we go…

TL;DR

# create new project as the parent
$ mkdir new_parent_project
$ cd new_parent_project
$ git init
$ touch .gitignore
$ git ci -am "initial commit"

# merge project A into subdirectory A
$ git remote add -f projA /path/to/projA
$ git merge -s ours --no-commit projA/master
$ git read-tree --prefix=subdirA/ -u projA/master
$ git ci -m "merging projA into subdirA"

# merge project B into subdirectory B
$ git remote add -f projB /path/to/projB
$ git merge -s ours --no-commit projB/master
$ git read-tree --prefix=subdirB/ -u projB/master
$ git ci -m "merging projB into subdirB"

The most common use case for sub-tree merges, that I’m aware of, is to merge another git repository into a subdirectory in an existing repository. There are quite a few tutorials which cover these steps. In fact, the second two sets of commands above do exactly that. However, I discovered that in order to merge two repositories into a new repository, the new repository must already have a prior commit in it. Otherwise, the sub-tree merges will not work as planned. So, as in the first set of commands above, be sure to create at least one initial commit prior to doing the sub-tree merges. It can be as trivial as committing an empty file. But without it, the merges will not work correctly. Armed with this knowledge, you can follow the tutorial on GitHub on merging sub-trees. Or you can follow along with me here.

Create Parent Repo

First, create a new, empty project to act as the parent project for our two existing repositories.

Jason@BRUTUS ~/dev
$ mkdir parent

Jason@BRUTUS ~/dev
$ cd parent/

Jason@BRUTUS ~/dev/parent
$ git init
Initialized empty Git repository in ~/dev/parent/.git/

Now we need to create the initial commit. This is essential.

Jason@BRUTUS ~/dev/parent (master #)
$ touch .gitignore

Jason@BRUTUS ~/dev/parent (master #)
$ git ci -am "initial commit"
[master (root-commit) fc6f5ad] initial commit
 0 files changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 .gitignore

Merge Project A Into Subdirectory

Next, we add a remote to the first project we’d like to import. We’ll give the remote a name (projectA) and pass the -f option so that it will fetch the contents of this remote immediately.

Jason@BRUTUS ~/dev/parent (master)
$ git remote add -f projectA /path/to/projectA
Updating projectA
warning: no common commits
remote: Counting objects: 16, done.
remote: Compressing objects: 100% (16/16), done.
remote: Total 16 (delta 7), reused 0 (delta 0)
Unpacking objects: 100% (16/16), done.
From /path/to/projectA
 * [new branch]      master     -> projectA/master

Now, let’s run a merge but not commit the result (--no-commit flag). We also need to specify the merge strategy ours with the -s switch.

Jason@BRUTUS ~/dev/parent (master)
$ git merge -s ours --no-commit projectA/master
Automatic merge went well; stopped before committing as requested

Now that we are in merging mode, we’ll read in the tree from the remote, taking care to provide a subdirectory into which the subproject will go. This is specified with with --prefix switch. Also, add the -u flag to update the working tree with our changes.

Jason@BRUTUS ~/dev/parent (master|MERGING)
$ git read-tree --prefix=projA/ -u projectA/master

The remote has been merged into its own subdirectory and the changes have been staged. Now we can simply commit them.

Jason@BRUTUS ~/dev/parent (master +|MERGING)
$ git ci -m "merging project A into subdirectory"
[master 4d2d50d] merging project A into subdirectory

Merge Project B Into Subdirectory

At this point, we have Project A merged into its own subdirectory within our new parent project. Merging in Project B uses the same simple steps as above.

Jason@BRUTUS ~/dev/parent (master)
$ git remote add -f projectB /path/to/projectB
Updating projectB
warning: no common commits
remote: Counting objects: 47, done.
remote: Compressing objects: 100% (47/47), done.
remote: Total 47 (delta 23), reused 0 (delta 0)
Unpacking objects: 100% (47/47), done.
From /path/to/projectB
 * [new branch]      master     -> projectB/master

Jason@BRUTUS ~/dev/parent (master)
$ git merge -s ours --no-commit projectB/master
Automatic merge went well; stopped before committing as requested

Jason@BRUTUS ~/dev/parent (master|MERGING)
$ git read-tree --prefix=projB/ -u projectB/master

Jason@BRUTUS ~/dev/parent (master +|MERGING)
$ git ci -m "merging project B into subdirectory"
[master 8f41792] merging project B into subdirectory

Pulling In Updates

If the original repositories (Projects A and B in this example) continue to live on elsewhere as separate projects, you can easily pull in updates to your new parent repo. Using the sub-tree merge strategy, the updates will be applied properly to the applicable subdirectory.

Jason@BRUTUS ~/dev/parent (master)
$ git pull -s subtree projectA master

However, if you no longer have any need for the original repositories, they can be deleted and the remotes in your new parent project can safely be removed.

Below is a screenshot of a repository after two sub-tree merges. The repositories that I merged were two separate userstyles: one for using tab color for notifications (gtab) and another for adding S/MIME icons to gmail’s inbox (gmail). Each of these two projects have their own history that was maintained after the merge. Now they are each in their own subdirectory in a common userstyles git repository. As you can see, the two projects each have their own lines of development that do not include any common ancestry until the merge point.

 
 

Tags: